C# 使用具有值类型的属性和 Delegate.CreateDelegate

Thi*_*heT 4 c# reflection primitive delegates value-type

使用 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,当我调用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."

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

Ser*_*rvy 5

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

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

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

public object GetPropValue(string name)
{
    return GetType().GetProperty(name).GetValue(this);
}
Run Code Online (Sandbox Code Playgroud)

如果你想返回一个Func<object>每次调用都会获取值的值,只需在该反射调用周围创建一个 lambda:

public Func<object> GetPropValue2(string name)
{
    return () => GetType().GetProperty(name).GetValue(this);
}
Run Code Online (Sandbox Code Playgroud)