Подтвердить что ты не робот

Преобразование базового класса в производный класс

Можно ли в С# явно преобразовать объект базового класса в один из его производных классов? В настоящее время я думаю, что мне нужно создать конструктор для моих производных классов, которые принимают объект базового класса в качестве параметра и копируют значения свойств. Мне не очень нравится эта идея, поэтому я хотел бы избежать ее, если это возможно.

Это не похоже, что он должен работать (объект создается как новая база, поэтому память не должна выделяться для дополнительных членов производного класса), но С#, похоже, позволяет мне это сделать:

class BaseClass
{
  ... some stuff ...
}

class DerivedClass : BaseClass
{
    public bool MyDerivedProperty{ get; set; }
}


static void Main(string[] args)
{
    BaseClass myBaseObject = new BaseClass();
    DerivedClass myDerivedObject = myBaseObject as DerivedClass;

    myDerivedObject.MyDerivedProperty = true;
}
4b9b3361

Ответ 1

Нет, нет встроенного способа конвертировать класс, как вы говорите. Самый простой способ сделать это - сделать то, что вы предложили: создать конструктор DerivedClass(BaseClass). Другие варианты в основном выходят для автоматизации копирования свойств из базы в производный экземпляр, например. используя отражение.

Код, который вы опубликовали с помощью as, будет скомпилирован, как я уверен, вы видели, но при запуске будет выбрано исключение с нулевой ссылкой, потому что myBaseObject as DerivedClass будет оцениваться до null, так как это не экземпляр DerivedClass.

Ответ 2

Это невозможно. но вы можете использовать Object Mapper, например AutoMapper

Пример:

class A
{
    public int IntProp { get; set; }
}
class B
{
    public int IntProp { get; set; }
    public string StrProp { get; set; }
}

В global.asax или запуске приложения:

AutoMapper.Mapper.CreateMap<A, B>();

Использование:

var b = AutoMapper.Mapper.Map<B>(a);

Он легко настраивается с помощью свободного API.

Ответ 3

Я нашел одно решение для этого, не сказав это лучшим, но он чувствует себя чистым для меня и не требует каких-либо серьезных изменений в моем коде. Мой код был похож на ваш, пока я не понял, что он не работает.

Мой базовый класс

public class MyBaseClass
{
   public string BaseProperty1 { get; set; }
   public string BaseProperty2 { get; set; }
   public string BaseProperty3 { get; set; }
   public string BaseProperty4 { get; set; }
   public string BaseProperty5 { get; set; }
}

Мой производный класс

public class MyDerivedClass : MyBaseClass
{
   public string DerivedProperty1 { get; set; }
   public string DerivedProperty2 { get; set; }
   public string DerivedProperty3 { get; set; }
}

Предыдущий метод получения заполненного базового класса

public MyBaseClass GetPopulatedBaseClass()
{
   var myBaseClass = new MyBaseClass();

   myBaseClass.BaseProperty1 = "Something"
   myBaseClass.BaseProperty2 = "Something else"
   myBaseClass.BaseProperty3 = "Something more"
   //etc...

   return myBaseClass;
}

До того, как я попытался это сделать, что дало мне возможность не выполнить ошибку

public MyDerivedClass GetPopulatedDerivedClass()
{
   var newDerivedClass = (MyDerivedClass)GetPopulatedBaseClass();

   newDerivedClass.UniqueProperty1 = "Some One";
   newDerivedClass.UniqueProperty2 = "Some Thing";
   newDerivedClass.UniqueProperty3 = "Some Thing Else";

   return newDerivedClass;
}

Я изменил свой код следующим образом и, похоже, работает и имеет больше смысла:

Старый

public MyBaseClass GetPopulatedBaseClass()
{
   var myBaseClass = new MyBaseClass();

   myBaseClass.BaseProperty1 = "Something"
   myBaseClass.BaseProperty2 = "Something else"
   myBaseClass.BaseProperty3 = "Something more"
   //etc...

   return myBaseClass;
}

New

public void FillBaseClass(MyBaseClass myBaseClass)
{
   myBaseClass.BaseProperty1 = "Something"
   myBaseClass.BaseProperty2 = "Something else"
   myBaseClass.BaseProperty3 = "Something more"
   //etc...
}

Старый

public MyDerivedClass GetPopulatedDerivedClass()
{
   var newDerivedClass = (MyDerivedClass)GetPopulatedBaseClass();

   newDerivedClass.UniqueProperty1 = "Some One";
   newDerivedClass.UniqueProperty2 = "Some Thing";
   newDerivedClass.UniqueProperty3 = "Some Thing Else";

   return newDerivedClass;
}

New

public MyDerivedClass GetPopulatedDerivedClass()
{
   var newDerivedClass = new MyDerivedClass();

   FillBaseClass(newDerivedClass);

   newDerivedClass.UniqueProperty1 = "Some One";
   newDerivedClass.UniqueProperty2 = "Some Thing";
   newDerivedClass.UniqueProperty3 = "Some Thing Else";

   return newDerivedClass;
}

Ответ 4

Вы можете реализовать преобразование самостоятельно, но я бы не рекомендовал этого. Взгляните на Decorator Pattern, если вы хотите сделать это, чтобы расширить функциональность существующего объекта.

Ответ 5

Нет, это невозможно. Единственный возможный способ -

static void Main(string[] args)
{
    BaseClass myBaseObject = new DerivedClass();
    DerivedClass myDerivedObject = myBaseObject as DerivedClass;

    myDerivedObject.MyDerivedProperty = true;
}

Ответ 6

Нет, для этого нет встроенного преобразования. Вам нужно будет создать конструктор, как вы упомянули, или какой-либо другой метод преобразования.

Кроме того, поскольку BaseClass не является DerivedClass, myDerivedObject будет иметь значение null, а последняя строка выше выдает исключение null ref.