Мне не нравится иметь кучу методов "влево/вправо". Каждый раз, когда свойство добавляется или удаляется, я должен исправить каждый метод. И сам код просто выглядит... неправильным.
public Foo(Foo other)
{
this.Bar = other.Bar;
this.Baz = other.Baz;
this.Lur = other.Lur;
this.Qux = other.Qux;
this.Xyzzy= other.Xyzzy;
}
Действительно, это просто развернутый цикл, который выполняет итерации через свойства, копируя их между объектами. Так почему бы не быть честным в этом факте? Отражение на помощь!
public Foo(IFoo other)
{
foreach (var property in typeof(IFoo).GetProperties())
{
property.SetValue(this, property.GetValue(other, null), null);
}
}
Я могу просто попытаться заставить парадигму, которую я узнал от Lua на С#, но этот конкретный пример не кажется мне слишком вонючим. Отсюда я начал делать более сложные вещи, которые были чувствительны к порядку полей. Например, вместо того, чтобы иметь стек практически идентичных операторов if
для создания строки из полей, я просто перебираю их в нужном порядке:
public override string ToString()
{
var toJoin = new List<string>();
foreach (var property in tostringFields)
{
object value = property.GetValue(this, null);
if (value != null)
toJoin.Add(value.ToString());
}
return string.Join(" ", toJoin.ToArray());
}
private static readonly PropertyInfo[] tostringFields =
{
typeof(IFoo).GetProperty("Bar"),
typeof(IFoo).GetProperty("Baz"),
typeof(IFoo).GetProperty("Lur"),
typeof(IFoo).GetProperty("Qux"),
typeof(IFoo).GetProperty("Xyzzy"),
};
Итак, теперь у меня есть итеративность, которую я хотел, но у меня все еще есть стеки кода, отражающие каждое свойство, которое меня интересует (я также делаю это для CompareTo, используя другой набор свойств в другом порядке). Хуже того, это потеря сильной типизации. Это действительно начинает пахнуть.
Ну а как насчет использования атрибутов для каждого свойства для определения порядка? Я начал по этой дороге, и действительно, она работала хорошо, но это просто заставило все выглядело раздутым. Он отлично работает семантически, но я всегда опасаюсь использовать расширенные функции только потому, что они "опрятные". Использует ли рефлексия таким образом избыток? Есть ли еще какое-то другое решение проблемы с левым/правым кодом, которую я пропускаю?