Questo articolo è stato tradotto automaticamente. Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

Metodo Delegate.CreateDelegate (Type, Object, MethodInfo)

 

Data di pubblicazione: ottobre 2016

Crea un delegato del tipo specificato che rappresenta il metodo statico o il metodo di istanza indicato, con il primo argomento specificato.

Spazio dei nomi:   System
Assembly:  mscorlib (in mscorlib.dll)

public static Delegate CreateDelegate(
	Type type,
	object firstArgument,
	MethodInfo method
)

Parametri

type
Type: System.Type

Type del delegato da creare.

firstArgument
Type: System.Object

Oggetto a cui il delegato è associato oppure null per trattare method come static (Shared in Visual Basic).

method
Type: System.Reflection.MethodInfo

MethodInfo che descrive il metodo statico o il metodo di istanza che deve essere rappresentato dal delegato.

Valore restituito

Type: System.Delegate

Delegato del tipo specificato che rappresenta il metodo statico o di istanza specificato.

Exception Condition
ArgumentNullException

type è null.

-oppure-

method è null.

ArgumentException

type non eredita MulticastDelegate.

-oppure-

type non è un oggetto RuntimeType. Vedere tipi di Runtime nella Reflection.

-oppure-

method non può essere associato.

-oppure-

method non è un oggetto RuntimeMethodInfo. Vedere tipi di Runtime nella Reflection.

MissingMethodException

Non è possibile trovare il metodo Invoke di type.

MethodAccessException

Il chiamante non ha le autorizzazioni necessarie per accedere a method.

Chiamare questo overload del metodo è equivalente alla chiamata di CreateDelegate(Type, Object, MethodInfo, Boolean) overload del metodo e specificando true per throwOnBindFailure. Questi due overload forniscono il modo più flessibile per creare delegati. È possibile utilizzarli per creare delegati per statici o metodi di istanza e, facoltativamente, per specificare il primo argomento.

System_CAPS_noteNota

Se non si specifica un primo argomento, utilizzare il CreateDelegate(Type, MethodInfo) overload del metodo per ottenere prestazioni migliori.

Il tipo delegato e il metodo devono avere tipi restituiti compatibili. Ovvero, il tipo restituito di method deve essere assegnabile al tipo restituito di type.

Se firstArgument è fornito, viene passato a method ogni volta che viene richiamato il delegato; firstArgument viene definito da associare al delegato e il delegato per essere chiuso al primo argomento. Se method è static (Shared in Visual Basic), l'argomento elenco fornito quando si richiama il delegato include tutti i parametri, ad eccezione del primo; se method è un metodo di istanza, quindi firstArgument viene passato al parametro di istanza nascosto (rappresentato da this in c# o da Me in Visual Basic).

Se firstArgument viene fornito, il primo parametro di method deve essere un tipo di riferimento e firstArgument deve essere compatibile con questo tipo.

System_CAPS_importantImportante

Se method è static (Shared in Visual Basic) e il primo parametro è di tipo Object o ValueType, quindi firstArgument può essere un tipo di valore. In questo caso firstArgument automaticamente viene sottoposto a boxing. Conversione boxing automatico non avviene per gli altri argomenti, come in una funzione di Visual Basic o c# chiama.

Se firstArgument è un riferimento null e method è un metodo di istanza, il risultato dipende dalle firme del tipo delegato type e di method:

  • Se la firma di type includa in modo esplicito il primo parametro nascosto di method, il delegato rappresenta un metodo di istanza aperta. Quando il delegato viene richiamato, il primo argomento nell'elenco di argomenti viene passato al parametro di istanza nascosta method.

  • Se le firme di method e type corrispondenza (vale a dire tutti i tipi di parametro compatibili), quindi il delegato per essere chiuso un riferimento null. Richiamare il delegato è simile in un'istanza null, che non è un aspetto particolarmente utile per eseguire la chiamata a un metodo di istanza.

Se firstArgument è un riferimento null e method è statico, il risultato dipende dalle firme del tipo delegato type e di method:

  • Se la firma di method e type corrispondenza (vale a dire tutti i tipi di parametro compatibili), il delegato per rappresentare un metodo statico aperto. Questo è il caso più comune per i metodi statici. In questo caso, è possibile ottenere prestazioni leggermente migliori utilizzando il CreateDelegate(Type, MethodInfo) overload del metodo.

  • Se la firma di type inizia con il secondo parametro di method e il resto dei tipi di parametro sono compatibili, quindi il delegato per essere chiuso un riferimento null. Quando il delegato viene richiamato, viene passato un riferimento null al primo parametro di method.

System_CAPS_noteNota

A partire dal .NET Framework 2.0 Service Pack 1, questo metodo può essere utilizzato per accedere ai metodi non pubblici, se il chiamante è stato concesso ReflectionPermission con il ReflectionPermissionFlag.RestrictedMemberAccess flag e se il set di concessioni dei metodi non pubblici è limitato al chiamante set o un sottoinsieme. Per informazioni, vedere Security Considerations for Reflection.

Per usare questa funzionalità, l'applicazione deve essere destinata a .NET Framework 3.5 o versione successiva.

Tipi di parametro e tipo restituito di un delegato deve essere compatibile con i tipi di parametro e un tipo restituito del metodo rappresentato dal delegato. i tipi non devono corrispondere esattamente.

System_CAPS_noteNota

In .NET Framework versioni 1.0 e 1.1, i tipi devono corrispondere esattamente.

Un parametro di un delegato è compatibile con il parametro di un metodo corrispondente se il tipo del parametro del delegato è più restrittivo rispetto al tipo del parametro del metodo. In questo modo si garantisce che un argomento passato al delegato possa essere passato in modo sicuro al metodo.

Analogamente, il tipo restituito di un delegato è compatibile con il tipo restituito di un metodo se il tipo restituito del metodo è più restrittivo rispetto al tipo restituito del delegato. In questo modo si garantisce la possibilità di eseguire in modo sicuro il cast del valore restituito del metodo nel tipo restituito del delegato.

Ad esempio, un delegato con un parametro di tipo Hashtable e un tipo restituito di Object può rappresentare un metodo con un parametro di tipo Object e un valore restituito di tipo Hashtable.

Un altro aspetto utile pensare alla flessibilità offerta da questo overload di CreateDelegate è che qualsiasi delegato specificato può rappresentare quattro diverse combinazioni di firma del metodo e il tipo di metodo (statico e metodi di istanza). Si consideri un tipo delegato D con un argomento di tipo C. Di seguito vengono descritti i metodi D può rappresentare, ignorando il tipo restituito poiché deve corrispondere in tutti i casi:

  • Dpuò rappresentare qualsiasi metodo di istanza che dispone esattamente un argomento di tipo C, indipendentemente dal tipo a cui appartiene il metodo di istanza. Quando CreateDelegate viene chiamato, firstArgument è un'istanza del tipo method appartiene, e il delegato risultante da chiudere tale istanza. (In modo rigido D può inoltre essere associato un riferimento null se firstArgument è un riferimento null.)

  • Dpuò rappresentare un metodo di istanza di C che non dispone di argomenti. Quando CreateDelegate viene chiamato, firstArgument è un riferimento null. Il delegato risultante rappresenta un metodo di istanza aperta e un'istanza di C è necessario specificare ogni volta che viene richiamato.

  • Dpuò rappresentare un metodo statico che accetta un argomento di tipo C, e che può appartenere a qualsiasi tipo. Quando CreateDelegate viene chiamato, firstArgument è un riferimento null. Il delegato risultante rappresenta un metodo statico aperto e un'istanza di C è necessario specificare ogni volta che viene richiamato.

  • Dpuò rappresentare un metodo statico che appartiene al tipo F e dispone di due argomenti, di tipo F e tipo C. Quando CreateDelegate viene chiamato, firstArgument è un'istanza di F. Il delegato risultante rappresenta un metodo statico che viene chiuso su tale istanza di F. Si noti che nel caso in cui F e C sono dello stesso tipo, il metodo statico con due argomenti di quel tipo. (In questo caso, D viene chiuso un riferimento null se firstArgument è un riferimento null.)

In questa sezione contiene tre esempi di codice. Nel primo esempio illustra i quattro tipi di delegati che possono essere creati: chiuso su un metodo di istanza, aperto su un metodo di istanza, aperto su un metodo statico e di chiusura su un metodo statico.

Nel secondo esempio vengono illustrati i tipi di parametro compatibili e tipi restituiti.

Mostra tutti i metodi che il tipo delegato possono rappresentare il terzo esempio di codice definisce un singolo tipo delegato.

Esempio 1

Esempio di codice riportato di seguito viene illustrato come le quattro modalità un delegato può essere creato tramite l'overload del CreateDelegate metodo.

System_CAPS_noteNota

Ci sono due overload di CreateDelegate metodo che specificano firstArgument e MethodInfo; le relative funzionalità deve essere uguale ad eccezione del fatto che uno consente di specificare se generare un errore di associazione e l'altra genera sempre un'eccezione. Questo esempio di codice utilizza entrambi gli overload.

Nell'esempio viene dichiarata una classe C con un metodo statico M2 e un metodo di istanza M1, e tre i tipi delegati: D1 accetta un'istanza di C e una stringa, D2 accetta una stringa e D3 non dispone di argomenti.

Una seconda classe denominata Example contiene il codice che crea i delegati.

  • Un delegato del tipo D2, chiuso su un'istanza di C, viene creato per il metodo di istanza M1. Viene richiamato con stringhe diverse, a indicare che l'istanza associata di C viene sempre utilizzato.

  • Un delegato del tipo D1, che rappresenta un metodo di istanza aperta, viene creato per il metodo di istanza M1. Un'istanza deve essere passata quando viene richiamato il delegato.

  • Un delegato del tipo D2, che rappresenta un metodo statico aperto, viene creato per il metodo statico M2.

  • Infine, un delegato del tipo D3, chiuso in una stringa, viene creato per il metodo statico M2. Il metodo viene richiamato per dimostrare l'utilizzo della stringa associata.

using System;
using System.Reflection;
using System.Security.Permissions;

// Declare three delegate types for demonstrating the combinations
// of static versus instance methods and open versus closed
// delegates.
//
public delegate void D1(C c, string s);
public delegate void D2(string s);
public delegate void D3();

// A sample class with an instance method and a static method.
//
public class C
{
    private int id;
    public C(int id) { this.id = id; }

    public void M1(string s) 
    { 
        Console.WriteLine("Instance method M1 on C:  id = {0}, s = {1}",
            this.id, s);
    }

    public static void M2(string s)
    { 
        Console.WriteLine("Static method M2 on C:  s = {0}", s); 
    }
}

public class Example
{
    public static void Main()
    {
        C c1 = new C(42);

        // Get a MethodInfo for each method.
        //
        MethodInfo mi1 = typeof(C).GetMethod("M1", 
            BindingFlags.Public | BindingFlags.Instance);
        MethodInfo mi2 = typeof(C).GetMethod("M2",
            BindingFlags.Public | BindingFlags.Static);

        D1 d1;
        D2 d2;
        D3 d3;


        Console.WriteLine("\nAn instance method closed over C.");
        // In this case, the delegate and the
        // method must have the same list of argument types; use
        // delegate type D2 with instance method M1.
        //
        Delegate test = 
            Delegate.CreateDelegate(typeof(D2), c1, mi1, false);

        // Because false was specified for throwOnBindFailure 
        // in the call to CreateDelegate, the variable 'test'
        // contains null if the method fails to bind (for 
        // example, if mi1 happened to represent a method of  
        // some class other than C).
        //
        if (test != null)
        {
            d2 = (D2) test;

            // The same instance of C is used every time the 
            // delegate is invoked.
            d2("Hello, World!");
            d2("Hi, Mom!");
        }


        Console.WriteLine("\nAn open instance method.");
        // In this case, the delegate has one more 
        // argument than the instance method; this argument comes
        // at the beginning, and represents the hidden instance
        // argument of the instance method. Use delegate type D1
        // with instance method M1.
        //
        d1 = (D1) Delegate.CreateDelegate(typeof(D1), null, mi1);

        // An instance of C must be passed in each time the 
        // delegate is invoked.
        //
        d1(c1, "Hello, World!");
        d1(new C(5280), "Hi, Mom!");


        Console.WriteLine("\nAn open static method.");
        // In this case, the delegate and the method must 
        // have the same list of argument types; use delegate type
        // D2 with static method M2.
        //
        d2 = (D2) Delegate.CreateDelegate(typeof(D2), null, mi2);

        // No instances of C are involved, because this is a static
        // method. 
        //
        d2("Hello, World!");
        d2("Hi, Mom!");


        Console.WriteLine("\nA static method closed over the first argument (String).");
        // The delegate must omit the first argument of the method.
        // A string is passed as the firstArgument parameter, and 
        // the delegate is bound to this string. Use delegate type 
        // D3 with static method M2. 
        //
        d3 = (D3) Delegate.CreateDelegate(typeof(D3), 
            "Hello, World!", mi2);

        // Each time the delegate is invoked, the same string is
        // used.
        d3();
    }
}

/* This code example produces the following output:

An instance method closed over C.
Instance method M1 on C:  id = 42, s = Hello, World!
Instance method M1 on C:  id = 42, s = Hi, Mom!

An open instance method.
Instance method M1 on C:  id = 42, s = Hello, World!
Instance method M1 on C:  id = 5280, s = Hi, Mom!

An open static method.
Static method M2 on C:  s = Hello, World!
Static method M2 on C:  s = Hi, Mom!

A static method closed over the first argument (String).
Static method M2 on C:  s = Hello, World!
 */

Esempio 2

Esempio di codice seguente viene illustrata la compatibilità dei tipi di parametro e i tipi restituiti.

System_CAPS_noteNota

Nell'esempio viene utilizzata la CreateDelegate(Type, MethodInfo) overload del metodo. L'utilizzo di altri overload che accettano MethodInfo è simile.

L'esempio di codice definisce una classe base denominata Base e una classe denominata Derived che deriva da Base. La classe derivata ha un static (Shared in Visual Basic) denominata metodo MyMethod con un parametro di tipo Base e un tipo restituito di Derived. L'esempio di codice definisce anche un delegato denominato Example che ha un parametro di tipo Derived e un tipo restituito di Base.

Nell'esempio di codice viene illustrato che il delegato denominato Example può essere utilizzato per rappresentare il metodo MyMethod. Il metodo può essere associato al delegato perché:

  • Il tipo di parametro del delegato (Derived) è più restrittivo rispetto al tipo di parametro del MyMethod (Base), in modo che sia sempre possibile passare l'argomento del delegato da MyMethod.

  • Il tipo restituito di MyMethod (Derived) è più restrittivo rispetto al tipo di parametro del delegato (Base), in modo che è sempre sicuro il cast del tipo restituito del metodo per il tipo restituito del delegato.

L'esempio di codice non produce alcun output.

using System;
using System.Reflection;

// Define two classes to use in the demonstration, a base class and 
// a class that derives from it.
//
public class Base {}

public class Derived : Base
{
    // Define a static method to use in the demonstration. The method 
    // takes an instance of Base and returns an instance of Derived.  
    // For the purposes of the demonstration, it is not necessary for 
    // the method to do anything useful. 
    //
    public static Derived MyMethod(Base arg)
    {
        Base dummy = arg;
        return new Derived();
    }
}

// Define a delegate that takes an instance of Derived and returns an
// instance of Base.
//
public delegate Base Example(Derived arg);

class Test
{
    public static void Main()
    {
        // The binding flags needed to retrieve MyMethod.
        BindingFlags flags = BindingFlags.Public | BindingFlags.Static;

        // Get a MethodInfo that represents MyMethod.
        MethodInfo minfo = typeof(Derived).GetMethod("MyMethod", flags);

        // Demonstrate contravariance of parameter types and covariance
        // of return types by using the delegate Example to represent
        // MyMethod. The delegate binds to the method because the
        // parameter of the delegate is more restrictive than the 
        // parameter of the method (that is, the delegate accepts an
        // instance of Derived, which can always be safely passed to
        // a parameter of type Base), and the return type of MyMethod
        // is more restrictive than the return type of Example (that
        // is, the method returns an instance of Derived, which can
        // always be safely cast to type Base). 
        //
        Example ex = 
            (Example) Delegate.CreateDelegate(typeof(Example), minfo);

        // Execute MyMethod using the delegate Example.
        //        
        Base b = ex(new Derived());
    }
}

Esempio 3

Esempio di codice seguente mostra tutti i metodi rappresenta un singolo tipo delegato, utilizzando il CreateDelegate metodo per creare i delegati.

System_CAPS_noteNota

Ci sono due overload di CreateDelegate metodo che specificano firstArgument e MethodInfo; le relative funzionalità deve essere uguale ad eccezione del fatto che uno consente di specificare se generare un errore di associazione e l'altra genera sempre un'eccezione. Questo esempio di codice utilizza entrambi gli overload.

L'esempio di codice definisce due classi, C e Fe un tipo delegato D con un argomento di tipo C. Le classi corrispondenti statici e metodi di istanza M1, M3, e M4e la classe C include inoltre un metodo di istanza M2 che non dispone di argomenti.

Una terza classe denominata Example contiene il codice che crea i delegati.

  • I delegati sono creati per l'istanza metodo M1 di tipo C e tipo F; ognuna viene chiuso su un'istanza del rispettivo tipo. Metodo M1 di tipo C consente di visualizzare il ID le proprietà dell'istanza associata e dell'argomento.

  • Viene creato un delegato per il metodo M2 di tipo C. Si tratta di un delegato di istanza aperta, in cui l'argomento del delegato rappresenta il primo argomento nascosto sul metodo di istanza. Il metodo non ha altri argomenti. Viene chiamato come se fosse un metodo statico.

  • I delegati vengono creati per il metodo statico M3 di tipo C e tipo F; questi delegati sono static aperti.

  • Infine, i delegati vengono creati per il metodo statico M4 di tipo C e tipo F; ogni metodo presenta il tipo dichiarante come primo argomento e viene fornita un'istanza del tipo, in modo che i delegati sono chiusa relativi primi argomenti. Metodo M4 di tipo C consente di visualizzare il ID le proprietà dell'istanza associata e dell'argomento.

using System;
using System.Reflection;
using System.Security.Permissions;

// Declare a delegate type. The object of this code example
// is to show all the methods this delegate can bind to.
//
public delegate void D(C c);

// Declare two sample classes, C and F. Class C has an ID
// property so instances can be identified.
//
public class C
{
    private int id;
    public int ID { get { return id; }}
    public C(int id) { this.id = id; }

    public void M1(C c) 
    { 
        Console.WriteLine("Instance method M1(C c) on C:  this.id = {0}, c.ID = {1}",
            this.id, c.ID);
    }

    public void M2() 
    { 
        Console.WriteLine("Instance method M2() on C:  this.id = {0}",
            this.id);
    }

    public static void M3(C c)
    { 
        Console.WriteLine("Static method M3(C c) on C:  c.ID = {0}", c.ID); 
    }

    public static void M4(C c1, C c2) 
    { 
        Console.WriteLine("Static method M4(C c1, C c2) on C:  c1.ID = {0}, c2.ID = {1}",
            c1.ID, c2.ID);
    }
}

public class F
{
    public void M1(C c) 
    { 
        Console.WriteLine("Instance method M1(C c) on F:  c.ID = {0}",
            c.ID);
    }

    public static void M3(C c)
    { 
        Console.WriteLine("Static method M3(C c) on F:  c.ID = {0}", c.ID); 
    }

    public static void M4(F f, C c) 
    { 
        Console.WriteLine("Static method M4(F f, C c) on F:  c.ID = {0}",
            c.ID);
    }
}


public class Example
{
    public static void Main()
    {
        C c1 = new C(42);
        C c2 = new C(1491);
        F f1 = new F();

        D d;

        // Instance method with one argument of type C.
        MethodInfo cmi1 = typeof(C).GetMethod("M1"); 
        // Instance method with no arguments.
        MethodInfo cmi2 = typeof(C).GetMethod("M2"); 
        // Static method with one argument of type C.
        MethodInfo cmi3 = typeof(C).GetMethod("M3"); 
        // Static method with two arguments of type C.
        MethodInfo cmi4 = typeof(C).GetMethod("M4"); 

        // Instance method with one argument of type C.
        MethodInfo fmi1 = typeof(F).GetMethod("M1");
        // Static method with one argument of type C.
        MethodInfo fmi3 = typeof(F).GetMethod("M3"); 
        // Static method with an argument of type F and an argument 
        // of type C.
        MethodInfo fmi4 = typeof(F).GetMethod("M4"); 

        Console.WriteLine("\nAn instance method on any type, with an argument of type C.");
        // D can represent any instance method that exactly matches its
        // signature. Methods on C and F are shown here.
        //
        d = (D) Delegate.CreateDelegate(typeof(D), c1, cmi1);
        d(c2);
        d = (D) Delegate.CreateDelegate(typeof(D), f1, fmi1);
        d(c2);

        Console.WriteLine("\nAn instance method on C with no arguments.");
        // D can represent an instance method on C that has no arguments;
        // in this case, the argument of D represents the hidden first
        // argument of any instance method. The delegate acts like a 
        // static method, and an instance of C must be passed each time
        // it is invoked.
        //
        d = (D) Delegate.CreateDelegate(typeof(D), null, cmi2);
        d(c1);

        Console.WriteLine("\nA static method on any type, with an argument of type C.");
        // D can represent any static method with the same signature.
        // Methods on F and C are shown here.
        //
        d = (D) Delegate.CreateDelegate(typeof(D), null, cmi3);
        d(c1);
        d = (D) Delegate.CreateDelegate(typeof(D), null, fmi3);
        d(c1);

        Console.WriteLine("\nA static method on any type, with an argument of");
        Console.WriteLine("    that type and an argument of type C.");
        // D can represent any static method with one argument of the
        // type the method belongs and a second argument of type C.
        // In this case, the method is closed over the instance of
        // supplied for the its first argument, and acts like an instance
        // method. Methods on F and C are shown here.
        //
        d = (D) Delegate.CreateDelegate(typeof(D), c1, cmi4);
        d(c2);
        Delegate test = 
            Delegate.CreateDelegate(typeof(D), f1, fmi4, false);

        // This final example specifies false for throwOnBindFailure 
        // in the call to CreateDelegate, so the variable 'test'
        // contains Nothing if the method fails to bind (for 
        // example, if fmi4 happened to represent a method of  
        // some class other than F).
        //
        if (test != null)
        {
            d = (D) test;
            d(c2);
        }
    }
}

/* This code example produces the following output:

An instance method on any type, with an argument of type C.
Instance method M1(C c) on C:  this.id = 42, c.ID = 1491
Instance method M1(C c) on F:  c.ID = 1491

An instance method on C with no arguments.
Instance method M2() on C:  this.id = 42

A static method on any type, with an argument of type C.
Static method M3(C c) on C:  c.ID = 42
Static method M3(C c) on F:  c.ID = 42

A static method on any type, with an argument of
    that type and an argument of type C.
Static method M4(C c1, C c2) on C:  c1.ID = 42, c2.ID = 1491
Static method M4(F f, C c) on F:  c.ID = 1491
*/

ReflectionPermission

for accessing a non-public method when the grant set of the non-public method is restricted to the caller's grant set, or a subset thereof. Associated enumeration: F:System.Security.Permissions.ReflectionPermissionFlag.RestrictedMemberAccess

ReflectionPermission

for accessing a non-public method regardless of its grant set. Associated enumeration: F:System.Security.Permissions.ReflectionPermissionFlag.MemberAccess

ReflectionPermission

when invoked late-bound through mechanisms such as M:System.Type.InvokeMember(System.String,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object,System.Object[],System.Reflection.ParameterModifier[],System.Globalization.CultureInfo,System.String[]). Associated enumeration: F:System.Security.Permissions.ReflectionPermissionFlag.MemberAccess.

.NET Framework
Disponibile da 2.0
Libreria di classi portabile
Supportato in: piattaforme .NET portabili
Silverlight
Disponibile da 2.0
Windows Phone Silverlight
Disponibile da 7.0
Torna all'inizio
Mostra: