C# 将具有值类型的属性与 Delegate.CreateDelegate 结合使用

本文关键字:Delegate CreateDelegate 结合 属性 类型 | 更新日期: 2023-09-27 18:34:23

使用

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"作为参数传入时,我在调用Delegate.CreateDelegate消息时得到ArgumentException "Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type." 当使用任何返回基元/值类型(包括结构)的属性时,会发生这种情况。

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

C# 将具有值类型的属性与 Delegate.CreateDelegate 结合使用

从根本上说,你的一般方法是不可能的。 之所以能够将所有非值类型视为Func<object>,是因为依赖于逆变(相对于T Func<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);
}