Es relativamente fácil crear una función lambda que devolverá el valor de una propiedad de un objeto, incluso incluyendo propiedades profundas ...Crear acción lambda de expresión de función
Func<Category, string> getCategoryName = new Func<Category, string>(c => c.Name);
y esto puede ser llamado como de la siguiente manera ...
string categoryName = getCategoryName(this.category);
Pero, dado única la función resultante por encima (o la expresión utilizada originalmente para crear la función), ¿alguien puede proporcionar una manera fácil crear la acción de oposición ...
Action<Category, string> setCategoryName = new Action<Category, string>((c, s) => c.Name = s);
... que permitirán el mismo valor de la propiedad que desea establecer como sigue?
setCategoryName(this.category, "");
en cuenta que estoy buscando una manera de crear la acción mediante programación de la función o expresión - espero que he demostrado que yo ya sé cómo crear manualmente.
Estoy abierto a respuestas que funcionen tanto en .net 3.5 como en 4.0.
Gracias.
ACTUALIZACIÓN:
Tal vez no estoy siendo claro en mi pregunta, así que vamos a tratar y demostrar más claramente lo que estoy tratando de hacer.
tengo el siguiente método (que he creado a los efectos de esta pregunta) ...
void DoLambdaStuff<TObject, TValue>(TObject obj, Expression<Func<TObject, TValue>> expression) {
Func<TObject, TValue> getValue = expression.Compile();
TValue stuff = getValue(obj);
Expression<Action<TObject, TValue>> assignmentExpression = (o, v) => Expression<TObject>.Assign(expression, Expression.Constant(v, typeof(TValue)));
Action<TObject, TValue> setValue = assignmentExpression.Compile();
setValue(obj, stuff);
}
Lo que estoy buscando es ¿cómo puedo crear el "assignmentExpression" dentro del código para que Puedo compilarlo en setValue? Me imagino que está relacionado con Expression.Assign, pero simplemente no puedo calcular la combinación correcta de parámetros para completar el código.
El resultado final es ser capaz de llamar a
Category category = *<get object from somewhere>*;
this.DoLambdaStuff(category, c => c.Name);
y esto a su vez creará un captador y definidor de la propiedad "Nombre" del objeto Categoría.
La versión anterior compila, pero cuando llamo a setValue() da como resultado una ArgumentException con "La expresión debe poder escribirse".
Gracias de nuevo.
Realmente no entiendo a qué se refiere al hacerlo se opuso de forma automática a manual. Sin embargo, si desea establecer propiedades y decidir qué propiedad desea establecer en tiempo de ejecución, debe usar el reflejo. Además, puede usar el árbol de expresiones para construir expresiones lambda en tiempo de ejecución. – Henri