2017-11-27 1 views
2

Ich habe eine Eigenschaft in einer DLL, die ich benutze Reflection-Funktion in C#. Ich möchte die Eigenschaft festlegen und der Eigenschaftstyp ist ein Delegattyp.Wie legen Sie den Eigenschaftswert mithilfe der Reflektion in C# fest, wenn es sich bei der Eigenschaft um einen Delegattyp handelt?

Bitte lassen Sie mich die Schritte zur Einstellung der Eigenschaft mit der Reflektion wissen.

Ich weiß, dass SetValue-Methode verwendet werden muss, um dies zu tun, aber nicht wissen, wie die Eigenschaft des Delegatentyps festgelegt wird.

SetValue (objectName, 1, null) soll eine Integer-Eigenschaft mithilfe von Reflection festlegen, weiß aber nicht, wie die Eigenschaft des Delegate-Typs festgelegt wird.

Wie deklariert man eine Variable des Delegate-Eigenschaftstyps und initialisiert sie mit Reflection?

+0

Möchten Sie ein * Ereignis * setzen/hinzufügen? Z.B. 'Button.Klicken'? –

Antwort

2

Es ist ziemlich einfach

Bei einer Klasse mit einem Delegierten Eigenschaft wie

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

wir es über Reflexion einstellen können wie so

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(); 
} 

Beachten Sie, dass wir ein geworfen haben Lambda-Ausdruck zu einem Delegattyp, hier System.Action weil es keinen Typ-Inferenzkontext gibt, aber das ist unwichtig, es ist nur eine von vielen Möglichkeiten, ein va zu erhalten lue eines Delegattyps.

, die uns zum zweiten Teil Ihrer Frage jedoch führt:

Wie eine Variable des Delegierten Objekttyp deklarieren und initialisieren es mithilfe von Reflektion?

Wir müssen einen Delegate-Wert eines Typs erstellen, der der deklarierten Eigenschaft entspricht. In diesem Fall war die Eigenschaft System.Action.

1

Auf der einfachsten Ebene legen Sie es auf die gleiche Weise stellen Sie die int Eigenschaft:

diese Klasse Angenommen:

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

die Eigenschaft Rahmen:

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); 

Wenn der Delegat enthält Ein Typ, der als Argument nicht öffentlich ist, kann je nach Kovarianz/Kontravarianz trotzdem mithilfe eines Objekts festgelegt werden.

die Klasse Unter der Annahme, wie unten, die Immobilie mit Action<object> Einstellung funktioniert immer noch

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

Wenn der Delegattyp selbst intern Sie müssen eine Instanz dieser internen Delegattyp erstellen:

Unter der Annahme:

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

internal delegate void Internal(Arg arg); 

können Sie verwenden:

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); 

Hinweis: Der obige Code funktioniert, weil wir erstellt einen Delegaten (Action<object>), die mit den Internal Delegierten kompatibel sein können (die Argumente kein explizites Casting benötigen) und verwendet, um die METHOD dieser Delegierten neu erstellen aus interner Delegierter. Abhängig vom Typ des zu erstellenden Delegierten mag dies kniffliger sein, aber ohne weitere Informationen sollte dieses Beispiel ein guter Ausgangspunkt sein.

Verwandte Themen