Odio avere un sacco di metodi "sinistra/destra". Ogni volta che una proprietà viene aggiunta o rimossa, devo correggere ogni metodo. E il codice stesso sembra ... sbagliato.Come utilizzare la riflessione per semplificare costruttori e confronti?
public Foo(Foo other)
{
this.Bar = other.Bar;
this.Baz = other.Baz;
this.Lur = other.Lur;
this.Qux = other.Qux;
this.Xyzzy= other.Xyzzy;
}
In realtà questo è solo un loop srotolato che consente di scorrere le proprietà, copiandoli tra gli oggetti. Quindi, perché non essere onesti su questo fatto? Riflessione in soccorso!
public Foo(IFoo other)
{
foreach (var property in typeof(IFoo).GetProperties())
{
property.SetValue(this, property.GetValue(other, null), null);
}
}
posso solo cercare di forzare un paradigma che ho imparato da Lua in C#, ma questo particolare esempio non sembra troppo puzzolente a me. Da qui, ho iniziato a fare alcune cose più complesse che erano sensibili all'ordine dei campi. Ad esempio, piuttosto che avere una pila di praticamente identiche if
dichiarazioni per comporre una stringa dai campi, ho appena scorrere su di loro nell'ordine desiderato:
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"),
};
Così ora ho l'iterabilità che volevo, ma ho ancora ho stack di codice che rispecchiano ogni proprietà a cui sono interessato (lo sto facendo anche per CompareTo, usando un diverso insieme di proprietà in un ordine diverso). Peggio ancora, è la perdita della tipizzazione forte. Questo sta davvero iniziando a sentire l'odore.
E che dire degli attributi su ogni proprietà per definire l'ordine? Ho iniziato su questa strada e in effetti ha funzionato bene, ma ha semplicemente reso tutto gonfio. Funziona alla grande semanticamente, ma sono sempre cauto nell'usare funzioni avanzate solo perché sono "pulite". Sta usando il riflesso in questo modo eccessivo? C'è qualche altra soluzione al problema del codice sinistro/destro che mi manca?
i'dd aggiungere un tag di lingua per ottenere più spettatori – Toad
Tenete a mente, la riflessione viene sempre con un calo di prestazioni in C#. Quanto spesso manipolerai Foos come questo? Una soluzione ibrida potrebbe essere quella di utilizzare Reflection.Emit e memorizzare nella cache il codice risultante: avvio più lento, esecuzione rapida. – zildjohn01
C# 4.0 viene fornito con compilatore incorporato, che può essere utile per generare codice e usarlo, per ora abbiamo anche problemi simili ma abbiamo progettato una soluzione utilizzando le strutture di classi XML e usiamo il nostro metodo di generazione del codice per creare classi che genera molti altri metodi che dipendono dai nomi dei memebers, è fondamentalmente un ORML ma fa tutto automaticamente. –