Я иногда использую подход, который напоминает ответы с помощью внедрения свойств, но сохраняет код чище.
Вместо базового класса / интерфейса с набором свойств он содержит только (виртуальный) метод Initialize (), который действует как «конструктор бедняка».
Затем вы можете позволить каждому классу обрабатывать свою собственную инициализацию так же, как это делал бы конструктор, что также добавляет удобный способ обработки цепочек наследования.
Если часто оказываются в ситуациях, когда я хочу, чтобы каждый класс в цепочке инициализировал свои уникальные свойства, а затем вызывал метод Initialize () его родителя, который в свою очередь инициализировал уникальные свойства родителя и так далее. Это особенно полезно при наличии разных классов, но с похожей иерархией, например бизнес-объектов, которые отображаются в / из DTO: s.
Пример, использующий общий словарь для инициализации:
void Main()
{
var values = new Dictionary<string, int> { { "BaseValue", 1 }, { "DerivedValue", 2 } };
Console.WriteLine(CreateObject<Base>(values).ToString());
Console.WriteLine(CreateObject<Derived>(values).ToString());
}
public T CreateObject<T>(IDictionary<string, int> values)
where T : Base, new()
{
var obj = new T();
obj.Initialize(values);
return obj;
}
public class Base
{
public int BaseValue { get; set; }
public virtual void Initialize(IDictionary<string, int> values)
{
BaseValue = values["BaseValue"];
}
public override string ToString()
{
return "BaseValue = " + BaseValue;
}
}
public class Derived : Base
{
public int DerivedValue { get; set; }
public override void Initialize(IDictionary<string, int> values)
{
base.Initialize(values);
DerivedValue = values["DerivedValue"];
}
public override string ToString()
{
return base.ToString() + ", DerivedValue = " + DerivedValue;
}
}