4

使用 Jon Skeet 的文章使反射飞起来并探索委托作为指南,我尝试使用 Delegate.CreateDelegate 方法将属性复制为委托。这是一个示例类:

public class PropertyGetter
{
    public int Prop1 {get;set;}
    public string Prop2 {get;set;}

    public object GetPropValue(string propertyName)
    {
        var property = GetType().GetProperty(propertyName).GetGetMethod();
        propertyDelegate = (Func<object>)Delegate.CreateDelegate(typeof(Func<object>), this, property);

        return propertyDelegate();
    }
}

我遇到的问题是,当我调用GetPropValue并作为参数传入时"Prop1",我得到一个带有消息ArgumentException的调用 当使用任何返回原始/值类型(包括结构)的属性时会发生这种情况。Delegate.CreateDelegate"Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type."

有人知道一种方法可以在这里同时使用引用类型和值类型吗?

4

1 回答 1

5

从根本上说,您的一般方法是不可能的。您能够采用所有非值类型并将它们视为 a 的Func<object>原因是依靠逆变(Func<T>相对于 逆变T)。根据语言规范,逆变不支持值类型。

当然,如果您不依赖于使用这种方法,问题会更容易。

如果您只想获取值,请使用以下PropertyInfo.GetValue方法:

public object GetPropValue(string name)
{
    return GetType().GetProperty(name).GetValue(this);
}

如果您想返回一个Func<object>在调用时会获取该值的值,只需围绕该反射调用创建一个 lambda:

public Func<object> GetPropValue2(string name)
{
    return () => GetType().GetProperty(name).GetValue(this);
}
于 2013-10-08T19:16:10.720 回答