代码之家  ›  专栏  ›  技术社区  ›  Dror Helper

如何将泛型属性作为参数传递给函数?

  •  5
  • Dror Helper  · 技术社区  · 16 年前

    我需要编写一个函数,它接收一个属性作为参数,并执行它的getter。

    如果我需要传递函数/委托,我将使用:

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

    是否有类似的方法来定义一个属性,以便我可以在函数代码中调用它的getter和/或setter?

    5 回复  |  直到 14 年前
        1
  •  8
  •   Nir    16 年前

    可以使用反射,可以为get/set访问器获取一个MethodInfo对象并调用它的invoke方法。

    代码示例假定您同时具有get和set访问器,如果要在生产代码中使用此访问器,则必须添加错误处理:

    例如,要获取对象obj的属性foo的值,可以编写:

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

    设置:

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

    因此,您可以将obj.getType().getProperty(“foo”).getAccessors()[0]传递给您的方法并执行它的invoke方法。

    一种更简单的方法是使用匿名方法(这将在.NET 2.0或更高版本中工作),让我们使用稍微修改过的代码版本示例:

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

    对于作为类SomeClass一部分的int类型的名为foo的属性:

    SomeClass obj = new SomeClass();
    func<SomeClass,int>(delegate(SomeClass o){return o.Foo;},obj);
    
        2
  •  11
  •   Bartosz Pierzchlewicz    14 年前

    你也可以写一些像:

    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);
            }
    

    调用示例:

    DbComputerSet cs = new DbComputerSet();
    cs.Method<DbComputerSet, string>(set => set.Code);
    
        3
  •  3
  •   Martijn    16 年前

    属性只是方法的语法糖。

    我认为你不能修改一个属性,使它成为一个“你可以调用的getter”实体。

    但是,您可以创建一个getPropertyValue()方法,并像传递委托一样传递它。

        4
  •  2
  •   aku    16 年前

    @德鲁尔帮手,

    恐怕你不能那样做。编译器生成get-propertyname和set-propertyname方法,但不使用反射就无法访问这些方法。在我看来,你能做的最好的就是创造出 系统.反射.属性信息 对象系统 参数并返回propinfo.getvalue(obj,空);

        5
  •  1
  •   Martijn    16 年前

    回复:Aku的回答:

    然后你必须先获得那个财产信息。似乎“使用反射”是解决更困难的C问题的标准答案,但是反射产生的代码维护起来并不那么困难。Dror,为什么不创建一个为您读取属性的委托呢?这是一个简单的一行程序,可能是解决您的问题最快、最漂亮的方法。