2014-02-07 5 views
0

У меня есть класс BaseClass, который имеет много свойств различных типов, включая списки и словари. Этот класс имеет три производных класса, которые имеют в них еще несколько свойств. Эти классы уже используются в большом приложении, поэтому изменение дизайна на данный момент невозможно.Как заполнить значения свойств объекта из его базового объекта

Так производные классы, как:

public class DerivedClass1 : BaseClass 
{ 
    public string PropertyOne { get; set; } 
} 

public class DerivedClass2 : BaseClass 
{ 
    public string PropertyTwo { get; set; } 
} 

public class DerivedClass3 : BaseClass 
{ 
    public string PropertyThree { get; set; } 
} 

Мне нужно выполнить полиморфизм, когда я десериализация этих классов на основе свойства, которая находится в базовом классе. Поэтому каждый раз, когда объект Json десериализуется в BaseClass, мне нужно проверить это значение свойства и создать правильный конкретный класс. Для этого мне нужен метод, как PopulateFrom (данном случае BaseClass, BaseClass fromObject), так что я могу назвать это таким образом:

var deserializedObjet = Serializer.Deserialize(jsonString); 
switch(deserializedObjet.ConcreteType) 
{ 
    case 1: 
     return new DerivedClass1().PopulateFrom(deserializedObjet); 
    case 2: 
     return new DerivedClass2().PopulateFrom(deserializedObjet); 
    case 3: 
     return new DerivedClass3().PopulateFrom(deserializedObjet); 
} 

Производные классы не имеют никаких данных в строке Json. То, что они делают, это то, что они получают одни и те же данные, но выполняют разные операции над ними или представляют их по-другому, поэтому мне просто нужно десериализовать Json в BaseClass.

Я знаю, что StackTrace.Text имеет аналогичный метод, но этот метод был добавлен с версии 4, которая не является бесплатной.

+0

Если вы десериализуете JSON на «BaseClass», тогда он будет игнорировать сериализованные значения свойств производных классов. Вам нужно снова десериализоваться в правильный класс, как только вы выясните, какой из них он есть. –

+0

Извините, я, вероятно, не упомянул проблему должным образом. Производные классы не имеют данных в строке Json. Они делают то, что получают одни и те же данные, но выполняют разные операции над ними или представляют их по-другому. – Aref

ответ

0

Вы можете создать требуемый экземпляр класса, скопировать значения свойств из текущего базового экземпляра в вновь созданный с отражением. Вы можете найти образец ниже (он должен быть устранен до компиляции)

static void PopulateFrom(this BaseClass dest, BaseClass source) //extension method will not modify legacy code and can be added to the any static class 
{ 
    var properties = source.GetType().GetProperties(public only); 
    foreach (var pi in properties) 
     if (pi.CanRead && pi.CanWrite) 
      pi.SetValue(dest, pi.GetValue(source, null), null); //this will work only for classes inherited from BaseClass 
} 

Также вы можете переопределить оператор присваивания в BaseClass и скопировать значение свойств с ним.

+0

Будет ли это работать и для списков и словарей? – Aref

+0

@Aref конечно! Вы получите объект назначения со свойством List1 (или Array2), который указывает на то же свойство List1 (или Array2), что и исходный объект, например. Однако я хотел бы отметить, что сериализовать словарь нельзя, и вам нужно добавить свойство fake KeyValuePair [], чтобы получить словарь, сериализованный с помощью XmlSerializer – oleksa

Смежные вопросы