2009-12-11 10 views
6

Ich habe die folgende Methode Unterschrift:Überprüfen, ob ein `object [] args` eine Delegate-Instanz erfüllt?

public static void InvokeInFuture(Delegate method, params object[] args) 
{ 
    // ... 
} 

Die Delegierten und die Argumente sind für zukünftige Aufrufe zu einer Sammlung gespeichert.

Gibt es eine Möglichkeit, ob ich überprüfen kann, ob das arguments-Array die Delegiertenanforderungen erfüllt, ohne es aufzurufen?

Danke.

EDIT: Danke für die Reflektion Implementierung, aber ich suche nach einer integrierten Möglichkeit, dies zu tun. Ich möchte das Rad nicht reinvertieren, das .NET Framework hat diese Überprüfung bereits in Delegate.DynamicInvoke() implementiert, eine Implementierung, die all die verrückten Spezialfälle behandelt, an die nur die Entwickler von Microsoft denken können, und Unit Testing und QA bestanden haben. Gibt es eine Möglichkeit, diese integrierte Implementierung zu verwenden?

Danke.

Antwort

6

Sie können Reflektion verwenden, um die Methodensignatur des Delegaten wie folgt abzurufen.

using System; 
using System.Reflection; 

bool ValidateDelegate(Delegate method, params object[] args) 
{ 
    ParameterInfo[] parameters = method.Method.GetParameters(); 
    if (parameters.Length != args.Length) { return false; } 

    for (int i = 0; i < parameters.Length; ++i) 
    { 
     if (parameters[i].ParameterType.IsValueType && args[i] == null || 
      !parameters[i].ParameterType.IsAssignableFrom(args[i].GetType())) 
     { 
      return false; 
     } 
    } 

    return true; 
} 
+0

es Schlagen Sie mich und Sie ein Codebeispiel hatte! +1 für vollständige Antwort auf seine Frage. –

+1

Ihr Code verarbeitet keine Vererbung, z. B. ein Argument vom Typ FileStream ist ein gültiges Stream-Argument. Ihr Code funktioniert möglicherweise, aber Tatsache ist, dass CLR überprüfen kann, ist er selbst in der delegate.Invoke(). Gibt es eine Möglichkeit, den Prüfcode der CLR wiederzuverwenden? Ich möchte der CLR vollständig entsprechen. – DxCK

+1

Hinweis: Sie sollten den Typ nicht wie folgt überprüfen, da dies für Varianteninstanzen false zurückgibt (z. B. wird ein Delegat, der "object" akzeptiert, false zurückgeben, wenn Sie eine "string" oder irgendetwas anderes übergeben). Ich würde vorschlagen, 'parameters [i] .ParameterType.IsAssignableFrom (args [i] .GetType())' zu verwenden und zusätzlich Prüfungen für den Werttyp und 'null' (' args [i] .getType() 'wird fehlschlagen wenn 'args [i]' 'null' ist). – Lucero

1

Sieht aus wie die framework im Grunde die oben tut, mit einer gewissen Logik Beseitigung sicherstellen, dass es eine Liste der bereits ausgewertet diejenigen hält.

Verwandte Themen