如何在运行时“调用” Action <,>类型的PropertyInfo

时间:2019-08-27 08:11:53

标签: c# reflection

我有一个通用类和一个Action<,>类型的属性。我想知道是否有一种方法可以在运行时中使用反射来实际调用此委托,而不仅仅是将值设置为此类属性(通过PropertyInfo.SetValue)。

我尝试了很多事情,例如使用表达式,伪演员表,阅读论坛,但没有一种解决方案对我有用。

解决方法: 我能想到的是创建一个内部调用委托的虚拟方法,并且通过反射很容易调用此方法。

public class Student
{
    public string Name { get; set; }
}

public class ConfigData<T> 
    where T: class
{
    public Action<T, object> ValueInjector { get; set; }

    public void SetValue(T entity, object valueToSet)
    {
        this.ValueInjector(entity, valueToSet);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var configObj = new ConfigData<Student>()
        {
            ValueInjector = (x, y) =>
            {
                // Some custom logic here
                x.Name = y.ToString();
            }
        };

        // Parameters
        Student student = new Student();
        object valueToSet = "Test";

        Type configType = configObj.GetType();
        PropertyInfo propertyInfo = configType.GetProperty("ValueInjector");

        // Invoke the property info somehow with the parameters ?

        // Workarround - invoke a dummy method instead
        MethodInfo methodInfo = configType.GetMethod("SetValue");
        methodInfo.Invoke(configObj, new object[] { student, valueToSet });

        Console.WriteLine(student.Name);
    }
}

我希望能够调用propertyInfo变量并将我已经拥有的两个参数(student, valueToSet)传递给它,因为我知道它代表可以运行的委托。

更新: 我按照@HimBromBeere的建议尝试了铸件。

//Error in runtime
var del = (Action)propertyInfo.GetValue(configObj, null);

//Error in runtime
var del = (Action<object, object>)propertyInfo.GetValue(configObj, null);

// Works but no generic
var del = (Action<Student, object>)propertyInfo.GetValue(configObj, null);
del.Invoke(student, valueToSet);

仅最后一次转换有效,我能够在委托人上调用Invoke(不需要DynamicInvoke),并且可以正常工作。但是,这不是解决方案,因为我不知道要在运行时强制转换的确切类型。我将其作为变量T。类似:

var del = (Action<T, object>)propertyInfo.GetValue(configObj, null);

因此,如果我设法制作出这样的通用类型:

var d1 = typeof(Action<,>);
Type[] typeArgs = { propertyInfo.DeclaringType.GenericTypeArguments[0], typeof(object) };
Type delegateType = d1.MakeGenericType(typeArgs);

可能有一种方法可以执行此转换并执行。还在想。

1 个答案:

答案 0 :(得分:1)

您可以将属性返回的值强制转换回委托,例如:

var del = (Action)propertyInfo.GetValue(configObj, null);

现在使用您的参数调用该代表:

del.DynamicInvoke(student, valueToset)