Odio tener un montón de métodos "izquierda/derecha". Cada vez que se agrega o elimina una propiedad, tengo que arreglar cada método. Y el código en sí mismo se ve ... mal.¿Cómo usar la reflexión para simplificar constructores y comparaciones?
public Foo(Foo other)
{
this.Bar = other.Bar;
this.Baz = other.Baz;
this.Lur = other.Lur;
this.Qux = other.Qux;
this.Xyzzy= other.Xyzzy;
}
Realmente esto es sólo un bucle desenrollado que recorre en iteración las propiedades, ellos copiando entre objetos. Entonces, ¿por qué no ser honesto sobre ese hecho? Reflexión al rescate!
public Foo(IFoo other)
{
foreach (var property in typeof(IFoo).GetProperties())
{
property.SetValue(this, property.GetValue(other, null), null);
}
}
que puede simplemente estar tratando de forzar un paradigma que aprendí de Lua en C#, pero este ejemplo en particular, no parece demasiado mal olor a mí. A partir de aquí, empecé a hacer cosas más complejas que eran sensibles al orden de los campos. Por ejemplo, en lugar de tener una pila de if
declaraciones casi idénticas a componer una cadena a partir de los campos, sólo iterar sobre ellos en el orden deseado:
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"),
};
Así que ahora tengo el iterabilidad que quería, pero todavía tienen montones de código duplicando cada propiedad que me interesa (también estoy haciendo esto para CompareTo, usando un conjunto diferente de propiedades en un orden diferente). Peor que eso es la pérdida de tipeo fuerte. Esto realmente está empezando a oler.
¿Y qué hay del uso de atributos en cada propiedad para definir el orden? Empecé por este camino y de hecho funcionó bien, pero simplemente hizo que todo pareciera hinchado. Funciona muy bien semánticamente, pero siempre tengo cuidado con el uso de funciones avanzadas simplemente porque son "ordenadas". ¿Usar la reflexión de esta manera es excesiva? ¿Hay alguna otra solución al problema del código izquierdo/derecho que me falta?
i'dd agregar una etiqueta de idioma para obtener más televidentes – Toad
Tenga en cuenta, la reflexión siempre viene con un impacto en el rendimiento en C#. ¿Con qué frecuencia estarás manipulando a Foos de esta manera? Una solución híbrida podría ser usar Reflection.Emit y almacenar en caché el código resultante: inicio más lento, ejecución rápida. – zildjohn01
C# 4.0 viene con un compilador incorporado, que puede ser útil para generar código y usarlo, por ahora también tenemos un problema similar, pero diseñamos una solución usando estructuras XML Class y usamos nuestro propio método de generación de código para construir clases que generar muchos otros métodos que dependen de los nombres de los miembros, es básicamente un ORML pero hace todo de forma automática. –