2008-09-21 18 views
5

Necesito escribir una función que reciba una propiedad como parámetro y ejecute su getter.¿Cómo pasar una propiedad genérica como parámetro a una función?

Si necesitaba para pasar una función/delegado habría utilizado:

delegate RET FunctionDelegate<T, RET>(T t); 

void func<T, RET>(FunctionDelegate function, T param, ...) 
{ 
    ... 
    return function.Invoke(param); 
} 

¿Hay una manera similar a definir una propiedad para que pudiera invocar es getter y/o colocador en el código de función?

Respuesta

7

Puede usar la reflexión, puede obtener un objeto MethodInfo para los accesadores get/set y llamar a su método Invoke.

El ejemplo de código se supone que tienen tanto un acceso get y set y que realmente tienen que añadir gestión de errores si quiere utilizar esto en el código de producción:

Por ejemplo, para obtener el valor de la propiedad de Foo del objeto obj puede escribir:

value = obj.GetType().GetProperty("Foo").GetAccessors()[0].Invoke(obj,null); 

para configurarlo:..

obj.GetType().GetProperty("Foo").GetAccessors()[1].Invoke(obj,new object[]{value}); 

lo que puede pasar obj.GetType() GetProperty ("foo") GetAccessors() [0] a su método y ejecutar su método Invoke.

una manera más fácil es utilizar métodos anónimos (esto funcionará en .NET 2.0 o posterior), vamos a usar una versión ligeramente modificada de su código de ejemplo:

delegate RET FunctionDelegate<T, RET>(T t); 

void func<T, RET>(FunctionDelegate<T,RET> function, T param, ...) 
{ 
    ... 
    return function(param); 
} 

de una propiedad denominada Foo de tipo int que es parte de una clase SomeClass: la respuesta de aku::

SomeClass obj = new SomeClass(); 
func<SomeClass,int>(delegate(SomeClass o){return o.Foo;},obj); 
3

Las propiedades son simplemente azúcares sintácticos para los métodos.

No creo que pueda modificar una propiedad de modo que se convierta en alguna entidad "a la que pueda llamar".

Sin embargo, puede crear un método GetPropertyValue() y pasarlo como si fuera un delegado.

+1

Esa es una muy buena idea a lo largo del principio KISS. Desafortunadamente en este momento no puedo usarlo :( El problema es que la propiedad que estoy usando no es parte de mi código. Y escribir un contenedor agrega sobrecarga No quiero en este punto –

2

@Dror ayudante,

me temo que no puede hacerlo de esa manera. El compilador genera los métodos get_PropertyName y set_PropertyName, pero no son accesibles sin usar Reflection. Lo mejor que puede hacer la IMO es crear una función que tome System.Reflection.ProperyInfo y System.Object params y devuelva propInfo.GetValue (obj, null);

1

Re

entonces usted tiene que obtener información de la propiedad en primer lugar. Parece que el "uso de la reflexión" es la respuesta estándar a las preguntas más difíciles de C#, pero la reflexión produce un código que no es tan difícil de mantener. Dror, ¿por qué no crear un delegado que lea la propiedad por ti? Es un simple trazador de líneas y es probablemente la solución más rápida y bonita para su problema.

+0

Sí, la solución implicará Reflexión de todos modos .Puede crear algunas envolturas útiles, pero prefiero tener un código más simple. La práctica muestra que las soluciones de reflexión complejas son muy frágiles. – aku

+1

Martijn - Ya le respondí sobre la creación de un envoltorio, aunque es una solución bastante simple, no es lo que necesito –

11

También puede escribir algo como:

static void Method<T, U>(this T obj, Expression<Func<T, U>> property) 
     { 
      var memberExpression = property.Body as MemberExpression; 
      //getter 
      U code = (U)obj.GetType().GetProperty(memberExpression.Member.Name).GetValue(obj, null); 
      //setter 
      obj.GetType().GetProperty(memberExpression.Member.Name).SetValue(obj, code, null); 
     } 

y el ejemplo de invocación:

DbComputerSet cs = new DbComputerSet(); 
cs.Method<DbComputerSet, string>(set => set.Code); 
+0

También existe la posibilidad de una Expresión Unaria que debe tener en cuenta. Mire aquí: http://stackoverflow.com/a/2916344/265877 – Alex

Cuestiones relacionadas