繁体   English   中英

当属性是委托类型时,如何在C#中使用反射设置属性值?

[英]How to set the property value using reflection in C# when the property is a delegate type?

我在C#中使用反射功能的dll中有一个属性。 我想设置属性,并且属性类型是委托类型。

请让我知道使用反射设置属性的步骤。

我知道需要使用SetValue方法来执行此操作,但不知道如何设置委托类型的属性。

SetValue(objectName,1,null)用于使用反射设置整数属性,但不知道如何设置委托类型的属性。

如何声明委托属性类型的变量并使用反射对其进行初始化?

这很简单

给定具有委托属性的类,例如

class A
{
    public Action Action { get; set; }
}

我们可以像这样通过反射来设置

void Main()
{
    var a = new A();

    var type = a.GetType();

    var delegateProperty = type.GetProperty(nameof(A.Action));

    delegateProperty.SetValue(a, (Action)(() => Console.WriteLine("via reflection")));

    a.Action();
}

请注意,我们必须将lambda表达式转换为委托类型,在这里为System.Action因为没有类型推断上下文,但这并不重要,它只是获得委托类型值的许多方法之一。

但这确实将我们引到您的问题的第二部分:

如何声明委托属性类型的变量并使用反射对其进行初始化?

我们需要创建与声明的属性匹配的类型的委托值。 在这种情况下,属性为System.Action

在最简单的级别上,可以使用设置int属性的相同方式进行设置:

假设此类:

public class MyClass
{
    internal Action<object> Simple { get; set; }
}

设置属性:

var type = typeof(MyClass);

var action = new Action<object>((o) => Console.WriteLine("Invoked with {0}", o));
var obj = new MyClass();
type.GetProperty("Simple", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(obj, action);

如果委托包含的参数类型不是公共的,则仍可以使用对象来设置它,具体取决于协方差/相反方差。

假设该类如下,仍然可以使用Action<object>设置属性

public class MyClass
{
    internal Action<Arg> Simple { get; set; }
}
internal class Arg { }

如果委托类型本身是内部的,则需要创建该内部委托类型的实例:

假设:

public class MyClass
{
    internal Internal Simple { get; set; }
}
internal class Arg { }

internal delegate void Internal(Arg arg);

您可以使用:

var type = typeof(MyClass);

var prop = type.GetProperty("Simple", BindingFlags.NonPublic | BindingFlags.Instance);
var action = new Action<object>((o) => Console.WriteLine("Invoked with {0}", o));
var delegateInsrtance = Delegate.CreateDelegate(prop.PropertyType, action.Target, action.Method);
var obj = new MyClass();
prop.SetValue(obj, delegateInsrtance);

注意:上面的代码行得通,因为我们创建了一个可以与Internal委托兼容的委托( Action<object> )(参数不需要任何显式强制转换),并使用该委托的methodInfo来创建新的内部委托。 根据您要创建的委托人的类型,这可能会比较棘手,但是如果没有更多信息,则此示例应该是一个很好的起点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM