I need to write a function that receives a property as a parameter and execute its getter.
我需要编写一个函数,它接收一个属性作为参数并执行其getter。
If I needed to pass a function/delegate I would have used:
如果我需要传递函数/委托,我会使用:
delegate RET FunctionDelegate<T, RET>(T t);
void func<T, RET>(FunctionDelegate function, T param, ...)
{
...
return function.Invoke(param);
}
Is there a similar way to define a property so that I could invoke it's getter and/or setter in the function code?
是否有类似的方法来定义属性,以便我可以在函数代码中调用它的getter和/或setter?
5 个解决方案
#1
8
You can use reflection, you can get a MethodInfo object for the get/set accessors and call it's Invoke method.
您可以使用反射,您可以获取get / set访问器的MethodInfo对象并调用它的Invoke方法。
The code example assumes you have both a get and set accessors and you really have to add error handling if you want to use this in production code:
代码示例假设您同时拥有get和set访问器,如果要在生产代码中使用它,则必须添加错误处理:
For example to get the value of property Foo of object obj you can write:
例如,要获取对象obj的属性Foo的值,您可以编写:
value = obj.GetType().GetProperty("Foo").GetAccessors()[0].Invoke(obj,null);
to set it:
设置它:
obj.GetType().GetProperty("Foo").GetAccessors()[1].Invoke(obj,new object[]{value});
So you can pass obj.GetType().GetProperty("Foo").GetAccessors()[0] to your method and execute it's Invoke method.
因此,您可以将obj.GetType()。GetProperty(“Foo”)。GetAccessors()[0]传递给您的方法并执行它的Invoke方法。
an easier way is to use anonymous methods (this will work in .net 2.0 or later), let's use a slightly modified version of your code example:
一种更简单的方法是使用匿名方法(这将在.net 2.0或更高版本中工作),让我们使用稍微修改过的代码示例版本:
delegate RET FunctionDelegate<T, RET>(T t);
void func<T, RET>(FunctionDelegate<T,RET> function, T param, ...)
{
...
return function(param);
}
for a property named Foo of type int that is part of a class SomeClass:
对于类型为int的名为Foo的属性,它是类SomeClass的一部分:
SomeClass obj = new SomeClass();
func<SomeClass,int>(delegate(SomeClass o){return o.Foo;},obj);
#2
11
You can also write something like:
你也可以这样写:
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);
}
and example of invocation:
和调用的例子:
DbComputerSet cs = new DbComputerSet();
cs.Method<DbComputerSet, string>(set => set.Code);
#3
3
Properties are simply syntactic sugar for methods.
属性只是方法的语法糖。
I don't think you can modify a property such that it becomes some entity "whose getter you can call".
我不认为你可以修改一个属性,使它成为一个“你可以调用它的getter”的实体。
You can however create a method GetPropertyValue() and pass that around as if it were a delegate.
但是,您可以创建一个方法GetPropertyValue(),并通过周围就好像它是一个代表。
#4
2
@Dror Helper,
I'm afraid you can't do it that way. Compiler generates get_PropertyName and set_PropertyName methods but they are not accessible without using Reflection. IMO best you can do is create function that takes System.Reflection.ProperyInfo and System.Object params and returns propInfo.GetValue(obj, null);
我担心你不能这样做。编译器生成get_PropertyName和set_PropertyName方法,但如果不使用Reflection,则无法访问它们。您可以做的最好的IMO是创建函数,它接受System.Reflection.ProperyInfo和System.Object参数并返回propInfo.GetValue(obj,null);
#5
1
Re: aku's answer:
回复:aku的回答:
Then you have to obtain that property info first. It seems "use reflection" is the standard answer to the harder C# questions, but reflection yields not-so-pretty hard-to-maintain code. Dror, why not just create a delegate that reads the property for you? It's a simple one-liner and is probably the quickest and prettiest solution to your problem.
然后你必须首先获得该属性信息。似乎“使用反射”是较难的C#问题的标准答案,但反射产生的代码并不那么难以维护。 Dror,为什么不创建一个为您读取属性的委托?这是一个简单的单行程,可能是解决您问题的最快,最漂亮的解决方案。
#1
8
You can use reflection, you can get a MethodInfo object for the get/set accessors and call it's Invoke method.
您可以使用反射,您可以获取get / set访问器的MethodInfo对象并调用它的Invoke方法。
The code example assumes you have both a get and set accessors and you really have to add error handling if you want to use this in production code:
代码示例假设您同时拥有get和set访问器,如果要在生产代码中使用它,则必须添加错误处理:
For example to get the value of property Foo of object obj you can write:
例如,要获取对象obj的属性Foo的值,您可以编写:
value = obj.GetType().GetProperty("Foo").GetAccessors()[0].Invoke(obj,null);
to set it:
设置它:
obj.GetType().GetProperty("Foo").GetAccessors()[1].Invoke(obj,new object[]{value});
So you can pass obj.GetType().GetProperty("Foo").GetAccessors()[0] to your method and execute it's Invoke method.
因此,您可以将obj.GetType()。GetProperty(“Foo”)。GetAccessors()[0]传递给您的方法并执行它的Invoke方法。
an easier way is to use anonymous methods (this will work in .net 2.0 or later), let's use a slightly modified version of your code example:
一种更简单的方法是使用匿名方法(这将在.net 2.0或更高版本中工作),让我们使用稍微修改过的代码示例版本:
delegate RET FunctionDelegate<T, RET>(T t);
void func<T, RET>(FunctionDelegate<T,RET> function, T param, ...)
{
...
return function(param);
}
for a property named Foo of type int that is part of a class SomeClass:
对于类型为int的名为Foo的属性,它是类SomeClass的一部分:
SomeClass obj = new SomeClass();
func<SomeClass,int>(delegate(SomeClass o){return o.Foo;},obj);
#2
11
You can also write something like:
你也可以这样写:
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);
}
and example of invocation:
和调用的例子:
DbComputerSet cs = new DbComputerSet();
cs.Method<DbComputerSet, string>(set => set.Code);
#3
3
Properties are simply syntactic sugar for methods.
属性只是方法的语法糖。
I don't think you can modify a property such that it becomes some entity "whose getter you can call".
我不认为你可以修改一个属性,使它成为一个“你可以调用它的getter”的实体。
You can however create a method GetPropertyValue() and pass that around as if it were a delegate.
但是,您可以创建一个方法GetPropertyValue(),并通过周围就好像它是一个代表。
#4
2
@Dror Helper,
I'm afraid you can't do it that way. Compiler generates get_PropertyName and set_PropertyName methods but they are not accessible without using Reflection. IMO best you can do is create function that takes System.Reflection.ProperyInfo and System.Object params and returns propInfo.GetValue(obj, null);
我担心你不能这样做。编译器生成get_PropertyName和set_PropertyName方法,但如果不使用Reflection,则无法访问它们。您可以做的最好的IMO是创建函数,它接受System.Reflection.ProperyInfo和System.Object参数并返回propInfo.GetValue(obj,null);
#5
1
Re: aku's answer:
回复:aku的回答:
Then you have to obtain that property info first. It seems "use reflection" is the standard answer to the harder C# questions, but reflection yields not-so-pretty hard-to-maintain code. Dror, why not just create a delegate that reads the property for you? It's a simple one-liner and is probably the quickest and prettiest solution to your problem.
然后你必须首先获得该属性信息。似乎“使用反射”是较难的C#问题的标准答案,但反射产生的代码并不那么难以维护。 Dror,为什么不创建一个为您读取属性的委托?这是一个简单的单行程,可能是解决您问题的最快,最漂亮的解决方案。