簡體   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