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 MethodBase.Invoke (Object, BindingFlags, Binder, Object[], CultureInfo)

 

Data di pubblicazione: ottobre 2016

Quando sottoposto a override in una classe derivata, richiama il metodo riflesso o un costruttore con parametri specificati.

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

public abstract object Invoke(
	object obj,
	BindingFlags invokeAttr,
	Binder binder,
	object[] parameters,
	CultureInfo culture
)

Parametri

obj
Type: System.Object

L'oggetto su cui richiamare il metodo o costruttore. Se un metodo è statico, questo argomento viene ignorato. Se un costruttore statico, questo argomento deve essere null o un'istanza della classe che definisce il costruttore.

invokeAttr
Type: System.Reflection.BindingFlags

Maschera di bit che è una combinazione di 0 o più flag di bit da BindingFlags. Se binder è null, questo parametro viene assegnato il valore Default; pertanto, qualsiasi elemento passato viene ignorato.

binder
Type: System.Reflection.Binder

Oggetto che consente il binding, la coercizione dei tipi di argomento, la chiamata dei membri e il recupero di oggetti MemberInfo tramite reflection. Se binder è null, verrà usato il binder predefinito.

parameters
Type: System.Object[]

Un elenco di argomenti per il metodo richiamato o il costruttore. Questa è una matrice di oggetti con lo stesso numero, ordine e tipo dei parametri del metodo o costruttore da richiamare. Se non sono presenti parametri, deve essere null.

Se il metodo o costruttore rappresentato da questa istanza accetta un parametro ByRef, non esiste nessun attributo speciale necessario per il parametro per richiamare il metodo o costruttore tramite la funzione. Qualsiasi oggetto in questa matrice non inizializzato in modo esplicito con un valore conterrà il valore predefinito per tale tipo di oggetto. Per gli elementi di tipo riferimento, questo valore è null. Per gli elementi di tipo di valore, questo valore è 0, 0.0 o false, a seconda del tipo di elemento specifico.

culture
Type: System.Globalization.CultureInfo

Istanza di CultureInfo usata per regolare la coercizione dei tipi. Se è null, per il thread corrente verrà usato l'oggetto CultureInfo. Si tratta di un parametro necessario per convertire un oggetto String che rappresenta, ad esempio, il numero 1000 in un valore Double, dal momento che questo numero è rappresentato in modo diverso nelle varie impostazioni cultura.

Valore restituito

Type: System.Object

Un Object contenente il valore restituito dal metodo richiamato o null nel caso di un costruttore o null Se il metodo restituito dal tipo è void. Prima di chiamare il metodo o costruttore Invoke verifica se l'utente dispone dell'autorizzazione di accesso e verifica che i parametri siano validi.

System_CAPS_warningAvviso

Elementi del parameters matrice che rappresentano i parametri dichiarati con la ref o out parola chiave può anche essere modificato.

Exception Condition
TargetException

Il obj parametro null e il metodo non è statico.

-oppure-

Il metodo non è dichiarato o ereditato dalla classe di obj.

-oppure-

Viene richiamato un costruttore statico, e obj non null né un'istanza della classe che ha dichiarato il costruttore.

ArgumentException

Il tipo di parameters parametro non corrisponde alla firma del metodo o costruttore tramite reflection dall'istanza.

TargetParameterCountException

Il parameters matrice non avere il numero corretto di argomenti.

TargetInvocationException

Il metodo richiamato o il costruttore genera un'eccezione.

MethodAccessException

Il chiamante non dispone dell'autorizzazione per eseguire il metodo o costruttore rappresentato dall'istanza corrente.

InvalidOperationException

Il tipo che dichiara il metodo è un tipo generico aperto. Vale a dire il Type.ContainsGenericParameters restituisce proprietà true per il tipo dichiarante.

Richiama dinamicamente, il metodo tramite reflection dall'istanza obj, e passa i parametri specificati. Se il metodo è statico, il obj parametro viene ignorato. Per i metodi non statici, obj deve essere un'istanza di una classe che eredita o dichiara il metodo e deve essere lo stesso tipo di questa classe. Se il metodo non dispone di parametri, il valore di parameters deve essere null. In caso contrario, il numero, tipo e l'ordine degli elementi in parameters deve essere identico al tipo, di numero e ordine dei parametri per il metodo tramite reflection dall'istanza.

Non è possibile omettere i parametri facoltativi nelle chiamate a Invoke. Per richiamare un metodo omettendo i parametri facoltativi, è necessario chiamare Type.InvokeMember invece.

System_CAPS_noteNota

Se questo overload del metodo viene utilizzato per richiamare un costruttore di istanza, l'oggetto specificato per obj viene reinizializzata; ovvero, tutti gli inizializzatori di istanza vengono eseguiti. Il valore restituito è null. Se viene richiamato un costruttore di classe, la classe viene reinizializzata; ovvero, vengono eseguiti tutti gli inizializzatori di classi. Il valore restituito è null.

Per i parametri primitivi passati per valore, viene eseguito un ampliamento normale (Int16 -> Int32, ad esempio). Per i parametri di riferimento passati per valore, (classe di base e classe di base al tipo di interfaccia, una classe derivata) è consentito un ampliamento normale del riferimento. Tuttavia, per i parametri primitivi passati per riferimento, i tipi devono corrispondere esattamente. Per i parametri di riferimento passati per riferimento, l'ampliamento normale viene ancora applicata.

Ad esempio, se il metodo riflesse dall'istanza è dichiarata come public boolean Compare(String a, String b), quindi parameters deve essere una matrice di Objects con lunghezza 2 tale parameters[0] = new Object("SomeString1") and parameters[1] = new Object("SomeString2").

Se un parametro del metodo corrente è un tipo di valore e l'argomento corrispondente in parameters è null, il runtime passa un'istanza del tipo di valore inizializzate su zero.

La reflection utilizza la ricerca di metodi dinamici quando si chiamano metodi virtuali. Si supponga, ad esempio, che la classe B eredita dalla classe e implementano un metodo virtuale denominato M. Si supponga di avere un MethodInfo oggetto che rappresenti M sulla classe A. Se si utilizza il Invoke metodo da richiamare M su un oggetto di tipo B, quindi reflection utilizzerà l'implementazione fornita dalla classe B. Anche se viene eseguito il cast di oggetti di tipo B ad A, viene utilizzata l'implementazione fornita dalla classe B (vedere l'esempio di codice riportato di seguito).

D'altra parte, se il metodo non virtuale, quindi reflection utilizzerà l'implementazione fornita dal tipo dal quale il MethodInfo è stato ottenuto, indipendentemente dal tipo dell'oggetto passato come destinazione.

Restrizioni di accesso vengono ignorate per un codice completamente attendibile. Vale a dire, proprietà, metodi, campi e costruttori privati accessibili e richiamate tramite reflection quando il codice è completamente attendibile.

Se il metodo richiamato genera un'eccezione, TargetInvocationException.GetException restituisce l'eccezione. Questa implementazione genera un NotSupportedException.

System_CAPS_noteNota

A partire dal .NET Framework 2.0 Service Pack 1, questo metodo può essere utilizzato per accedere a membri non pubblici se il chiamante sia stata concessa ReflectionPermission con il ReflectionPermissionFlag.RestrictedMemberAccess flag e se il set di concessioni dei membri non pubblici è limitato al chiamante insieme di autorizzazioni o un suo 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.

L'esempio seguente illustra tutti i membri della System.Reflection.Binder classe utilizzando un overload di Type.InvokeMember. Il metodo privato CanConvertFrom ricerca tipi compatibili per un determinato tipo. Per un altro esempio di richiamo dei membri in uno scenario di associazione personalizzata, vedere Dynamically Loading and Using Types.

using System;
using System.Reflection;
using System.Globalization;

public class MyBinder : Binder 
{
    public MyBinder() : base()
    {
    }
    private class BinderState
    {
        public object[] args;
    }
    public override FieldInfo BindToField(
        BindingFlags bindingAttr,
        FieldInfo[] match,
        object value,
        CultureInfo culture
        )
    {
        if(match == null)
            throw new ArgumentNullException("match");
        // Get a field for which the value parameter can be converted to the specified field type.
        for(int i = 0; i < match.Length; i++)
            if(ChangeType(value, match[i].FieldType, culture) != null)
                return match[i];
        return null;
    }
    public override MethodBase BindToMethod(
        BindingFlags bindingAttr,
        MethodBase[] match,
        ref object[] args,
        ParameterModifier[] modifiers,
        CultureInfo culture,
        string[] names,
        out object state
        )
    {
        // Store the arguments to the method in a state object.
        BinderState myBinderState = new BinderState();
        object[] arguments = new Object[args.Length];
        args.CopyTo(arguments, 0);
        myBinderState.args = arguments;
        state = myBinderState;
        if(match == null)
            throw new ArgumentNullException();
        // Find a method that has the same parameters as those of the args parameter.
        for(int i = 0; i < match.Length; i++)
        {
            // Count the number of parameters that match.
            int count = 0;
            ParameterInfo[] parameters = match[i].GetParameters();
            // Go on to the next method if the number of parameters do not match.
            if(args.Length != parameters.Length)
                continue;
            // Match each of the parameters that the user expects the method to have.
            for(int j = 0; j < args.Length; j++)
            {
                // If the names parameter is not null, then reorder args.
                if(names != null)
                {
                    if(names.Length != args.Length)
                        throw new ArgumentException("names and args must have the same number of elements.");
                    for(int k = 0; k < names.Length; k++)
                        if(String.Compare(parameters[j].Name, names[k].ToString()) == 0)
                            args[j] = myBinderState.args[k];
                }
                // Determine whether the types specified by the user can be converted to the parameter type.
                if(ChangeType(args[j], parameters[j].ParameterType, culture) != null)
                    count += 1;
                else
                    break;
            }
            // Determine whether the method has been found.
            if(count == args.Length)
                return match[i];
        }
        return null;
    }
    public override object ChangeType(
        object value,
        Type myChangeType,
        CultureInfo culture
        )
    {
        // Determine whether the value parameter can be converted to a value of type myType.
        if(CanConvertFrom(value.GetType(), myChangeType))
            // Return the converted object.
            return Convert.ChangeType(value, myChangeType);
        else
            // Return null.
            return null;
    }
    public override void ReorderArgumentArray(
        ref object[] args,
        object state
        )
    {
        // Return the args that had been reordered by BindToMethod.
        ((BinderState)state).args.CopyTo(args, 0);
    }
    public override MethodBase SelectMethod(
        BindingFlags bindingAttr,
        MethodBase[] match,
        Type[] types,
        ParameterModifier[] modifiers
        )
    {
        if(match == null)
            throw new ArgumentNullException("match");
        for(int i = 0; i < match.Length; i++)
        {
            // Count the number of parameters that match.
            int count = 0; 
            ParameterInfo[] parameters = match[i].GetParameters();
            // Go on to the next method if the number of parameters do not match.
            if(types.Length != parameters.Length)
                continue;
            // Match each of the parameters that the user expects the method to have.
            for(int j = 0; j < types.Length; j++)
                // Determine whether the types specified by the user can be converted to parameter type.
                if(CanConvertFrom(types[j], parameters[j].ParameterType))
                    count += 1;
                else
                    break;
            // Determine whether the method has been found.
            if(count == types.Length)
                return match[i];
        }
        return null;
    }
    public override PropertyInfo SelectProperty(
        BindingFlags bindingAttr,
        PropertyInfo[] match,
        Type returnType,
        Type[] indexes,
        ParameterModifier[] modifiers
        )
    {
        if(match == null)
            throw new ArgumentNullException("match");
        for(int i = 0; i < match.Length; i++)
        {
            // Count the number of indexes that match.
            int count = 0;
            ParameterInfo[] parameters = match[i].GetIndexParameters();
            // Go on to the next property if the number of indexes do not match.
            if(indexes.Length != parameters.Length)
                continue;
            // Match each of the indexes that the user expects the property to have.
            for(int j = 0; j < indexes.Length; j++)
                // Determine whether the types specified by the user can be converted to index type.
                if(CanConvertFrom(indexes[j], parameters[j].ParameterType))
                    count += 1;
                else
                    break;
            // Determine whether the property has been found.
            if(count == indexes.Length)
                // Determine whether the return type can be converted to the properties type.
                if(CanConvertFrom(returnType, match[i].PropertyType))
                    return match[i];
                else
                    continue;
        }
        return null;
    }
    // Determines whether type1 can be converted to type2. Check only for primitive types.
    private bool CanConvertFrom(Type type1, Type type2)
    {
        if(type1.IsPrimitive && type2.IsPrimitive)
        {
            TypeCode typeCode1 = Type.GetTypeCode(type1);
            TypeCode typeCode2 = Type.GetTypeCode(type2);
            // If both type1 and type2 have the same type, return true.
            if(typeCode1 == typeCode2)
                return true;
            // Possible conversions from Char follow.
            if(typeCode1 == TypeCode.Char)
                switch(typeCode2)
                {
                    case TypeCode.UInt16 : return true;
                    case TypeCode.UInt32 : return true;
                    case TypeCode.Int32  : return true;
                    case TypeCode.UInt64 : return true;
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from Byte follow.
            if(typeCode1 == TypeCode.Byte)
                switch(typeCode2)
                {
                    case TypeCode.Char   : return true;
                    case TypeCode.UInt16 : return true;
                    case TypeCode.Int16  : return true;
                    case TypeCode.UInt32 : return true;
                    case TypeCode.Int32  : return true;
                    case TypeCode.UInt64 : return true;
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from SByte follow.
            if(typeCode1 == TypeCode.SByte)
                switch(typeCode2)
                {
                    case TypeCode.Int16  : return true;
                    case TypeCode.Int32  : return true;
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from UInt16 follow.
            if(typeCode1 == TypeCode.UInt16)
                switch(typeCode2)
                {
                    case TypeCode.UInt32 : return true;
                    case TypeCode.Int32  : return true;
                    case TypeCode.UInt64 : return true;
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from Int16 follow.
            if(typeCode1 == TypeCode.Int16)
                switch(typeCode2)
                {
                    case TypeCode.Int32  : return true;
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from UInt32 follow.
            if(typeCode1 == TypeCode.UInt32)
                switch(typeCode2)
                {
                    case TypeCode.UInt64 : return true;
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from Int32 follow.
            if(typeCode1 == TypeCode.Int32)
                switch(typeCode2)
                {
                    case TypeCode.Int64  : return true;
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from UInt64 follow.
            if(typeCode1 == TypeCode.UInt64)
                switch(typeCode2)
                {
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from Int64 follow.
            if(typeCode1 == TypeCode.Int64)
                switch(typeCode2)
                {
                    case TypeCode.Single : return true;
                    case TypeCode.Double : return true;
                    default              : return false;
                }
            // Possible conversions from Single follow.
            if(typeCode1 == TypeCode.Single)
                switch(typeCode2)
                {
                    case TypeCode.Double : return true;
                    default              : return false;
                }
        }
        return false;
    }
}
public class MyClass1
{
    public short myFieldB;
    public int myFieldA; 
    public void MyMethod(long i, char k)
    {
        Console.WriteLine("\nThis is MyMethod(long i, char k)");
    }
    public void MyMethod(long i, long j)
    {
        Console.WriteLine("\nThis is MyMethod(long i, long j)");
    }
}
public class Binder_Example
{
    public static void Main()
    {
        // Get the type of MyClass1.
        Type myType = typeof(MyClass1);
        // Get the instance of MyClass1.
        MyClass1 myInstance = new MyClass1();
        Console.WriteLine("\nDisplaying the results of using the MyBinder binder.\n");
        // Get the method information for MyMethod.
        MethodInfo myMethod = myType.GetMethod("MyMethod", BindingFlags.Public | BindingFlags.Instance,
            new MyBinder(), new Type[] {typeof(short), typeof(short)}, null);
        Console.WriteLine(myMethod);
        // Invoke MyMethod.
        myMethod.Invoke(myInstance, BindingFlags.InvokeMethod, new MyBinder(), new Object[] {(int)32, (int)32}, CultureInfo.CurrentCulture);
    }
}

ReflectionPermission

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

ReflectionPermission

for accessing non-public members regardless of their 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 1.1
Silverlight
Disponibile da 2.0
Windows Phone Silverlight
Disponibile da 7.0
Torna all'inizio
Mostra: