Dynamisches Laden und Verwenden von TypenDynamically Loading and Using Types

Reflektion stellt Infrastruktur bereit, die von Sprachcompilern für die Implementierung impliziter später Bindungen verwendet wird.Reflection provides infrastructure used by language compilers to implement implicit late binding. Unter Binden versteht man das Auffinden der Deklaration (d.h. der Implementierung), die einem eindeutig festgelegten Typ entspricht.Binding is the process of locating the declaration (that is, the implementation) that corresponds to a uniquely specified type. Wenn dieser Prozess zur Runtime und nicht zum Zeitpunkt der Kompilierung stattfindet, wird von einer späten Bindung gesprochen.When this process occurs at run time rather than at compile time, it is called late binding. Visual Basic ermöglicht Ihnen, die implizite späte Bindung in Ihrem Code zu verwenden. Der Visual Basic-Compiler ruft eine Hilfsmethode auf, die mithilfe von Reflektion den Objekttyp abruft.Visual Basic allows you to use implicit late binding in your code; the Visual Basic compiler calls a helper method that uses reflection to obtain the object type. Aufgrund der an die Hilfsmethode übergebenen Argumente wird die entsprechende Methode zur Runtime aufgerufen.The arguments passed to the helper method cause the appropriate method to be invoked at run time. Diese Argumente sind die Instanz (ein Objekt), auf der die Methode aufgerufen werden muss, der Namen der aufgerufenen Methode (eine Zeichenfolge) und die Argumente, die an die aufgerufene Methode übergeben werden (ein Array von Objekten).These arguments are the instance (an object) on which to invoke the method, the name of the invoked method (a string), and the arguments passed to the invoked method (an array of objects).

Im folgenden Beispiel verwendet der Visual Basic-Compiler Reflektion implizit, um eine Methode für ein Objekt aufzurufen, dessen Typ zur Kompilierzeit nicht bekannt ist.In the following example, the Visual Basic compiler uses reflection implicitly to call a method on an object whose type is not known at compile time. Ein HelloWorld-Klasse verfügt über eine PrintHello-Methode, die „Hello World“ zusammen mit anderem Text ausgibt, der an die PrintHello-Methode übergeben wurde.A HelloWorld class has a PrintHello method that prints out "Hello World" concatenated with some text that is passed to the PrintHello method. Die in diesem Beispiel aufgerufene PrintHello-Methode ist eigentlich eine Type.InvokeMember-Methode. Im Visual Basic-Code kann die PrintHello-Methode aufgerufen werden, als ob der Typ des Objekts (helloObj) schon zur Kompilierzeit bekannt wäre (frühe Bindung) statt erst zur Runtime (späte Bindung).The PrintHello method called in this example is actually a Type.InvokeMember; the Visual Basic code allows the PrintHello method to be invoked as if the type of the object (helloObj) were known at compile time (early binding) rather than at run time (late binding).

Module Hello  
    Sub Main()  
        ' Sets up the variable.  
        Dim helloObj As Object  
        ' Creates the object.  
        helloObj = new HelloWorld()  
        ' Invokes the print method as if it was early bound  
        ' even though it is really late bound.  
        helloObj.PrintHello("Visual Basic Late Bound")  
    End Sub  
End Module  

Benutzerdefinierte BindungCustom Binding

Abgesehen davon, dass Reflektion implizit von Compilern für das späte Binden verwendet wird, kann sie auch explizit im Code für das späte Binden angewandt werden.In addition to being used implicitly by compilers for late binding, reflection can be used explicitly in code to accomplish late binding.

Die Common Language Runtime unterstützt verschiedene Programmiersprachen, wobei sich die Bindungsregeln dieser Sprachen unterscheiden.The common language runtime supports multiple programming languages, and the binding rules of these languages differ. Beim frühen Binden können Codegeneratoren den Bindungsvorgang vollständig steuern.In the early-bound case, code generators can completely control this binding. Beim späten Binden durch Reflektion muss der Vorgang durch eine benutzerdefinierte Bindung gesteuert werden.However, in late binding through reflection, binding must be controlled by customized binding. Die Binder-Klasse stellt die benutzerdefinierte Steuerung der Auswahl und des Aufrufs von Membern bereit.The Binder class provides custom control of member selection and invocation.

Mithilfe der benutzerdefinierten Bindung können Sie eine Assembly zur Runtime laden, Informationen über Typen in dieser Assembly abrufen, den gewünschten Typ angeben und dann für diesen Typ die Methoden aufrufen oder auf die Felder bzw. Eigenschaften zugreifen.Using custom binding, you can load an assembly at run time, obtain information about types in that assembly, specify the type that you want, and then invoke methods or access fields or properties on that type. Diese Technik ist hilfreich, wenn Sie den Typ eines Objekts zur Kompilierzeit nicht kennen, z.B., wenn der Objekttyp von der Benutzereingabe abhängt.This technique is useful if you do not know an object's type at compile time, such as when the object type is dependent on user input.

Das folgende Beispiel zeigt einen einfachen benutzerdefinierten Binder, der keine Argumenttypumwandlung bereitstellt.The following example demonstrates a simple custom binder that provides no argument type conversion. Der Code für Simple_Type.dll steht vor dem Hauptbeispiel.Code for Simple_Type.dll precedes the main example. Achten Sie darauf, dass Sie Simple_Type.dll erstellen und dann zur Buildzeit einen Verweis darauf in das Projekt einbinden.Be sure to build Simple_Type.dll and then include a reference to it in the project at build time.

// Code for building SimpleType.dll.
using namespace System;
using namespace System::Reflection;
using namespace System::Globalization;

namespace Simple_Type
{
    public ref class MySimpleClass
    {
    public:
        void MyMethod(String^ str, int i)
        {
            Console::WriteLine("MyMethod parameters: {0}, {1}", str, i);
        }

        void MyMethod(String^ str, int i, int j)
        {
            Console::WriteLine("MyMethod parameters: {0}, {1}, {2}",
                str, i, j);
        }
    };
}

using namespace Simple_Type;

namespace Custom_Binder
{
    // ****************************************************
    //  A simple custom binder that provides no
    //  argument type conversion.
    // ****************************************************
    public ref class MyCustomBinder : Binder
    {
    public:
        virtual MethodBase^ BindToMethod(
            BindingFlags bindingAttr,
            array<MethodBase^>^ match,
            array<Object^>^% args,
            array<ParameterModifier>^ modifiers,
            CultureInfo^ culture,
            array<String^>^ names,
            Object^% state) override
        {
            if (match == nullptr)
            {
                throw gcnew ArgumentNullException("match");
            }
            // Arguments are not being reordered.
            state = nullptr;
            // Find a parameter match and return the first method with
            // parameters that match the request.
            for each (MethodBase^ mb in match)
            {
                array<ParameterInfo^>^ parameters = mb->GetParameters();

                if (ParametersMatch(parameters, args))
                {
                    return mb;
                }
            }
            return nullptr;
        }

        virtual FieldInfo^ BindToField(BindingFlags bindingAttr,
            array<FieldInfo^>^ match, Object^ value, CultureInfo^ culture) override
        {
            if (match == nullptr)
            {
                throw gcnew ArgumentNullException("match");
            }
            for each (FieldInfo^ fi in match)
            {
                if (fi->GetType() == value->GetType())
                {
                    return fi;
                }
            }
            return nullptr;
        }

        virtual MethodBase^ SelectMethod(
            BindingFlags bindingAttr,
            array<MethodBase^>^ match,
            array<Type^>^ types,
            array<ParameterModifier>^ modifiers) override
        {
            if (match == nullptr)
            {
                throw gcnew ArgumentNullException("match");
            }

            // Find a parameter match and return the first method with
            // parameters that match the request.
            for each (MethodBase^ mb in match)
            {
                array<ParameterInfo^>^ parameters = mb->GetParameters();
                if (ParametersMatch(parameters, types))
                {
                    return mb;
                }
            }

            return nullptr;
        }

        virtual PropertyInfo^ SelectProperty(
            BindingFlags bindingAttr,
            array<PropertyInfo^>^ match,
            Type^ returnType,
            array<Type^>^ indexes,
            array<ParameterModifier>^ modifiers) override
        {
            if (match == nullptr)
            {
                throw gcnew ArgumentNullException("match");
            }
            for each (PropertyInfo^ pi in match)
            {
                if (pi->GetType() == returnType &&
                    ParametersMatch(pi->GetIndexParameters(), indexes))
                {
                    return pi;
                }
            }
            return nullptr;
        }

        virtual Object^ ChangeType(
            Object^ value,
            Type^ myChangeType,
            CultureInfo^ culture) override
        {
            try
            {
                Object^ newType;
                newType = Convert::ChangeType(value, myChangeType);
                return newType;
            }
            // Throw an InvalidCastException if the conversion cannot
            // be done by the Convert.ChangeType method.
            catch (InvalidCastException^)
            {
                return nullptr;
            }
        }

        virtual void ReorderArgumentArray(array<Object^>^% args,
            Object^ state) override
        {
            // No operation is needed here because BindToMethod does not
            // reorder the args array. The most common implementation
            // of this method is shown below.

            // ((BinderState^)state).args.CopyTo(args, 0);
        }

        // Returns true only if the type of each object in a matches
        // the type of each corresponding object in b.
    private:
        bool ParametersMatch(array<ParameterInfo^>^ a, array<Object^>^ b)
        {
            if (a->Length != b->Length)
            {
                return false;
            }
            for (int i = 0; i < a->Length; i++)
            {
                if (a[i]->ParameterType != b[i]->GetType())
                {
                    return false;
                }
            }
            return true;
        }

        // Returns true only if the type of each object in a matches
        // the type of each corresponding entry in b.
        bool ParametersMatch(array<ParameterInfo^>^ a, array<Type^>^ b)
        {
            if (a->Length != b->Length)
            {
                return false;
            }
            for (int i = 0; i < a->Length; i++)
            {
                if (a[i]->ParameterType != b[i])
                {
                    return false;
                }
            }
            return true;
        }
    };

    public ref class MyMainClass
    {
    public:
        static void Main()
        {
            // Get the type of MySimpleClass.
            Type^ myType = MySimpleClass::typeid;

            // Get an instance of MySimpleClass.
            MySimpleClass^ myInstance = gcnew MySimpleClass();
            MyCustomBinder^ myCustomBinder = gcnew MyCustomBinder();

            // Get the method information for the particular overload
            // being sought.
            MethodInfo^ myMethod = myType->GetMethod("MyMethod",
                BindingFlags::Public | BindingFlags::Instance,
                myCustomBinder, gcnew array<Type^> {String::typeid,
                int::typeid}, nullptr);
            Console::WriteLine(myMethod->ToString());

            // Invoke the overload.
            myType->InvokeMember("MyMethod", BindingFlags::InvokeMethod,
                myCustomBinder, myInstance,
                gcnew array<Object^> {"Testing...", (int)32});
        }
    };
}

int main()
{
    Custom_Binder::MyMainClass::Main();
}
// Code for building SimpleType.dll.
using System;
using System.Reflection;
using System.Globalization;
using Simple_Type;

namespace Simple_Type
{
    public class MySimpleClass
    {
        public void MyMethod(string str, int i)
        {
            Console.WriteLine("MyMethod parameters: {0}, {1}", str, i);
        }

        public void MyMethod(string str, int i, int j)
        {
            Console.WriteLine("MyMethod parameters: {0}, {1}, {2}",
                str, i, j);
        }
    }
}

namespace Custom_Binder
{
    class MyMainClass
    {
        static void Main()
        {
            // Get the type of MySimpleClass.
            Type myType = typeof(MySimpleClass);

            // Get an instance of MySimpleClass.
            MySimpleClass myInstance = new MySimpleClass();
            MyCustomBinder myCustomBinder = new MyCustomBinder();

            // Get the method information for the particular overload 
            // being sought.
            MethodInfo myMethod = myType.GetMethod("MyMethod", 
                BindingFlags.Public | BindingFlags.Instance,
                myCustomBinder, new Type[] {typeof(string), 
                typeof(int)}, null);
            Console.WriteLine(myMethod.ToString());
            
            // Invoke the overload.
            myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod, 
                myCustomBinder, myInstance,
                new Object[] {"Testing...", (int)32});
        }
    }

    // ****************************************************
    //  A simple custom binder that provides no
    //  argument type conversion.
    // ****************************************************
    class MyCustomBinder : Binder
    {
        public override MethodBase BindToMethod(
            BindingFlags bindingAttr,
            MethodBase[] match,
            ref object[] args,
            ParameterModifier[] modifiers,
            CultureInfo culture,
            string[] names,
            out object state)
        {
            if (match == null)
            {
                throw new ArgumentNullException("match");
            }
            // Arguments are not being reordered.
            state = null;
            // Find a parameter match and return the first method with
            // parameters that match the request.
            foreach (MethodBase mb in match)
            {
                ParameterInfo[] parameters = mb.GetParameters();

                if (ParametersMatch(parameters, args))
                {
                    return mb;
                }
            }
            return null;
        }

        public override FieldInfo BindToField(BindingFlags bindingAttr, 
            FieldInfo[] match, object value, CultureInfo culture)
        {
            if (match == null)
            {
                throw new ArgumentNullException("match");
            }
            foreach (FieldInfo fi in match)
            {
                if (fi.GetType() == value.GetType())
                {
                    return fi;
                }
            }
            return null;
        }

        public override MethodBase SelectMethod(
            BindingFlags bindingAttr,
            MethodBase[] match,
            Type[] types,
            ParameterModifier[] modifiers)
        {
            if (match == null)
            {
                throw new ArgumentNullException("match");
            }

            // Find a parameter match and return the first method with
            // parameters that match the request.
            foreach (MethodBase mb in match)
            {
                ParameterInfo[] parameters = mb.GetParameters();
                if (ParametersMatch(parameters, types))
                {
                    return mb;
                }
            }

            return null;
        }

        public override PropertyInfo SelectProperty(
            BindingFlags bindingAttr,
            PropertyInfo[] match,
            Type returnType,
            Type[] indexes,
            ParameterModifier[] modifiers)
        {
            if (match == null)
            {
                throw new ArgumentNullException("match");
            }
            foreach (PropertyInfo pi in match)
            {
                if (pi.GetType() == returnType &&
                    ParametersMatch(pi.GetIndexParameters(), indexes))
                {
                    return pi;
                }
            }
            return null;
        }

        public override object ChangeType(
            object value,
            Type myChangeType,
            CultureInfo culture)
        {
            try
            {
                object newType;
                newType = Convert.ChangeType(value, myChangeType);
                return newType;
            }
            // Throw an InvalidCastException if the conversion cannot
            // be done by the Convert.ChangeType method.
            catch (InvalidCastException)
            {
                return null;
            }
        }

        public override void ReorderArgumentArray(ref object[] args,
            object state)
        {
            // No operation is needed here because BindToMethod does not
            // reorder the args array. The most common implementation
            // of this method is shown below.

            // ((BinderState)state).args.CopyTo(args, 0);
        }

        // Returns true only if the type of each object in a matches
        // the type of each corresponding object in b.
        private bool ParametersMatch(ParameterInfo[] a, object[] b)
        {
            if (a.Length != b.Length)
            {
                return false;
            }
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i].ParameterType != b[i].GetType())
                {
                    return false;
                }
            }
            return true;
        }

        // Returns true only if the type of each object in a matches
        // the type of each corresponding entry in b.
        private bool ParametersMatch(ParameterInfo[] a, Type[] b)
        {
            if (a.Length != b.Length)
            {
                return false;
            }
            for (int i = 0; i < a.Length; i++)
            {
                if (a[i].ParameterType != b[i])
                {
                    return false;
                }
            }
            return true;
        }
    }
}
' Code for building SimpleType.dll.
Imports System.Reflection
Imports System.Globalization
Imports Simple_Type

Namespace Simple_Type
    Public Class MySimpleClass
        Public Sub MyMethod(str As String, i As Integer)
            Console.WriteLine("MyMethod parameters: {0}, {1}", str, i)
        End Sub

        Public Sub MyMethod(str As String, i As Integer, j As Integer)
            Console.WriteLine("MyMethod parameters: {0}, {1}, {2}",
                str, i, j)
        End Sub
    End Class
End Namespace

Namespace Custom_Binder
    Class MyMainClass
        Shared Sub Main()
            ' Get the type of MySimpleClass.
            Dim myType As Type = GetType(MySimpleClass)

            ' Get an instance of MySimpleClass.
            Dim myInstance As New MySimpleClass()
            Dim myCustomBinder As New MyCustomBinder()

            ' Get the method information for the particular overload
            ' being sought.
            Dim myMethod As MethodInfo = myType.GetMethod("MyMethod",
                BindingFlags.Public Or BindingFlags.Instance,
                myCustomBinder, New Type() {GetType(String),
                GetType(Integer)}, Nothing)
            Console.WriteLine(myMethod.ToString())

            ' Invoke the overload.
            myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod,
                myCustomBinder, myInstance,
                New Object() {"Testing...", CInt(32)})
        End Sub
    End Class

    ' ****************************************************
    '  A simple custom binder that provides no
    '  argument type conversion.
    ' ****************************************************
    Class MyCustomBinder
        Inherits Binder

        Public Overrides Function BindToMethod(bindingAttr As BindingFlags,
            match() As MethodBase, ByRef args As Object(),
            modIfiers() As ParameterModIfier, culture As CultureInfo,
            names() As String, ByRef state As Object) As MethodBase

            If match is Nothing Then
                Throw New ArgumentNullException("match")
            End If
            ' Arguments are not being reordered.
            state = Nothing
            ' Find a parameter match and return the first method with
            ' parameters that match the request.
            For Each mb As MethodBase in match
                Dim parameters() As ParameterInfo = mb.GetParameters()

                If ParametersMatch(parameters, args) Then
                    Return mb
                End If
            Next mb
            Return Nothing
        End Function

        Public Overrides Function BindToField(bindingAttr As BindingFlags,
            match() As FieldInfo, value As Object, culture As CultureInfo) As FieldInfo
            If match Is Nothing
                Throw New ArgumentNullException("match")
            End If
            For Each fi As FieldInfo in match
                If fi.GetType() = value.GetType() Then
                    Return fi
                End If
            Next fi
            Return Nothing
        End Function

        Public Overrides Function SelectMethod(bindingAttr As BindingFlags,
            match() As MethodBase, types() As Type,
            modifiers() As ParameterModifier) As MethodBase

            If match Is Nothing Then
                Throw New ArgumentNullException("match")
            End If

            ' Find a parameter match and return the first method with
            ' parameters that match the request.
            For Each mb As MethodBase In match
                Dim parameters() As ParameterInfo = mb.GetParameters()
                If ParametersMatch(parameters, types) Then
                    Return mb
                End If
            Next mb

            Return Nothing
        End Function

        Public Overrides Function SelectProperty(
            bindingAttr As BindingFlags, match() As PropertyInfo,
            returnType As Type, indexes() As Type,
            modIfiers() As ParameterModIfier) As PropertyInfo

            If match Is Nothing Then
                Throw New ArgumentNullException("match")
            End If
            For Each pi As PropertyInfo In match
                If pi.GetType() = returnType And
                    ParametersMatch(pi.GetIndexParameters(), indexes) Then
                    Return pi
                End If
            Next pi
            Return Nothing
        End Function

        Public Overrides Function ChangeType(
            value As Object,
            myChangeType As Type,
            culture As CultureInfo) As Object

            Try
                Dim newType As Object
                newType = Convert.ChangeType(value, myChangeType)
                Return newType
            ' Throw an InvalidCastException If the conversion cannot
            ' be done by the Convert.ChangeType method.
            Catch
                Return Nothing
            End Try
        End Function

        Public Overrides Sub ReorderArgumentArray(ByRef args() As Object, state As Object)
            ' No operation is needed here because BindToMethod does not
            ' reorder the args array. The most common implementation
            ' of this method is shown below.

            ' ((BinderState)state).args.CopyTo(args, 0)
        End Sub

        ' Returns true only If the type of each object in a matches
        ' the type of each corresponding object in b.
        Private Overloads Function ParametersMatch(a() As ParameterInfo, b() As Object) As Boolean
            If a.Length <> b.Length Then
                Return false
            End If
            For i As Integer = 0 To a.Length - 1
                If a(i).ParameterType <> b(i).GetType() Then
                    Return false
                End If
            Next i
            Return true
        End Function

        ' Returns true only If the type of each object in a matches
        ' the type of each corresponding enTry in b.
        Private Overloads Function ParametersMatch(a() As ParameterInfo,
            b() As Type) As Boolean

            If a.Length <> b.Length Then
                Return false
            End If
            For i As Integer = 0 To a.Length - 1
                If a(i).ParameterType <> b(i)
                    Return false
                End If
            Next
            Return true
        End Function
    End Class
End Namespace

InvokeMember und CreateInstanceInvokeMember and CreateInstance

Verwenden Sie Type.InvokeMember, um einen Member eines Typs aufzurufen.Use Type.InvokeMember to invoke a member of a type. Die CreateInstance-Methoden verschiedener Klassen wie Activator.CreateInstance und Assembly.CreateInstance sind spezielle Formen von InvokeMember, die neue Instanzen des angegebenen Typs erstellen.The CreateInstance methods of various classes, such as Activator.CreateInstance and Assembly.CreateInstance, are specialized forms of InvokeMember that create new instances of the specified type. Die Binder-Klasse wird in diesen Methoden für die Auflösung von Überladungen und die Koersion von Argumenten verwendet.The Binder class is used for overload resolution and argument coercion in these methods.

Im folgenden Beispiel werden drei mögliche Kombinationen der Argumentkoersion (Typkonvertierung) und Memberauswahl dargestellt.The following example shows the three possible combinations of argument coercion (type conversion) and member selection. Im 1. Fall ist keine Argumentkoersion oder Memberauswahl erforderlich.In Case 1, no argument coercion or member selection is needed. Im 2. Fall ist nur die Memberauswahl notwendig.In Case 2, only member selection is needed. Im 3. Fall muss nur die Argumentkoersion vorgenommen werden.In Case 3, only argument coercion is needed.

public ref class CustomBinderDriver
{
public:
    static void Main()
    {
        Type^ t = CustomBinderDriver::typeid;
        CustomBinder^ binder = gcnew CustomBinder();
        BindingFlags flags = BindingFlags::InvokeMethod | BindingFlags::Instance |
            BindingFlags::Public | BindingFlags::Static;
        array<Object^>^ args;

        // Case 1. Neither argument coercion nor member selection is needed.
        args = gcnew array<Object^> {};
        t->InvokeMember("PrintBob", flags, binder, nullptr, args);

        // Case 2. Only member selection is needed.
        args = gcnew array<Object^> {42};
        t->InvokeMember("PrintValue", flags, binder, nullptr, args);

        // Case 3. Only argument coercion is needed.
        args = gcnew array<Object^> {"5.5"};
        t->InvokeMember("PrintNumber", flags, binder, nullptr, args);
    }

    static void PrintBob()
    {
        Console::WriteLine("PrintBob");
    }

    static void PrintValue(long value)
    {
        Console::WriteLine("PrintValue({0})", value);
    }

    static void PrintValue(String^ value)
    {
        Console::WriteLine("PrintValue\"{0}\")", value);
    }

    static void PrintNumber(double value)
    {
        Console::WriteLine("PrintNumber ({0})", value);
    }
};

int main()
{
    CustomBinderDriver::Main();
}
public class CustomBinderDriver
{
    public static void Main()
    {
        Type t = typeof(CustomBinderDriver);
        CustomBinder binder = new CustomBinder();
        BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Instance |
            BindingFlags.Public | BindingFlags.Static;
        object[] args;

        // Case 1. Neither argument coercion nor member selection is needed.
        args = new object[] {};
        t.InvokeMember("PrintBob", flags, binder, null, args);

        // Case 2. Only member selection is needed.
        args = new object[] {42};
        t.InvokeMember("PrintValue", flags, binder, null, args);

        // Case 3. Only argument coercion is needed.
        args = new object[] {"5.5"};
        t.InvokeMember("PrintNumber", flags, binder, null, args);
    }

    public static void PrintBob()
    {
        Console.WriteLine("PrintBob");
    }

    public static void PrintValue(long value)
    {
        Console.WriteLine("PrintValue({0})", value);
    }
    
    public static void PrintValue(string value)
    {
        Console.WriteLine("PrintValue\"{0}\")", value);
    }

    public static void PrintNumber(double value)
    {
        Console.WriteLine("PrintNumber ({0})", value);
    }
}
Public Class CustomBinderDriver
    Public Shared Sub Main()
        Dim t As Type = GetType(CustomBinderDriver)
        Dim binder As New CustomBinder()
        Dim flags As BindingFlags = BindingFlags.InvokeMethod Or BindingFlags.Instance Or
            BindingFlags.Public Or BindingFlags.Static
        Dim args() As Object

        ' Case 1. Neither argument coercion nor member selection is needed.
        args = New object() {}
        t.InvokeMember ("PrintBob", flags, binder, Nothing, args)

        ' Case 2. Only member selection is needed.
        args = New object() {42}
        t.InvokeMember ("PrintValue", flags, binder, Nothing, args)

        ' Case 3. Only argument coercion is needed.
        args = New object() {"5.5"}
        t.InvokeMember("PrintNumber", flags, binder, Nothing, args)
    End Sub

    Public Shared Sub PrintBob()
        Console.WriteLine ("PrintBob")
    End Sub

    Public Shared Sub PrintValue(value As Long)
        Console.WriteLine("PrintValue ({0})", value)
    End Sub

    Public Shared Sub PrintValue(value As String)
        Console.WriteLine("PrintValue ""{0}"")", value)
    End Sub

    Public Shared Sub PrintNumber(value As Double)
        Console.WriteLine("PrintNumber ({0})", value)
    End Sub
End Class

Die Überladungsauflösung ist nötig, wenn mehr als ein Member mit demselben Namen verfügbar ist.Overload resolution is needed when more than one member with the same name is available. Die Methoden Binder.BindToMethod und Binder.BindToField werden zum Auflösen der Bindung zu einem einzelnes Member verwendet.The Binder.BindToMethod and Binder.BindToField methods are used to resolve binding to a single member. Binder.BindToMethod stellt außerdem die Auflösung von Eigenschaften über die Eigenschaftenaccessoren get und set bereit.Binder.BindToMethod also provides property resolution through the get and set property accessors.

BindToMethod gibt die aufzurufende MethodBase-Klasse oder einen NULL-Verweis zurück (Nothing in Visual Basic), wenn kein solcher Aufruf möglich ist.BindToMethod returns the MethodBase to invoke, or a null reference (Nothing in Visual Basic) if no such invocation is possible. Die Rückgabewert von MethodBase muss keiner der im match-Parameter enthaltenen sein, obwohl dies normalerweise der Fall ist.The MethodBase return value need not be one of those contained in the match parameter, although that is the usual case.

Wenn ByRef-Argumente vorhanden sind, kann der Aufrufer sie bei Bedarf wiederherstellen.When ByRef arguments are present, the caller might want to get them back. Aus diesem Grund ermöglicht es Binder einem Client, das Argumentarray wieder in seine ursprüngliche Form zu versetzen, wenn es von BindToMethod bearbeitet wurde.Therefore, Binder allows a client to map the array of arguments back to its original form if BindToMethod has manipulated the argument array. Dazu muss dem Aufrufer gewährleistet werden, dass die Reihenfolge der Argumente nicht verändert wurde.In order to do this, the caller must be guaranteed that the order of the arguments is unchanged. Wenn Argumente nach Namen übergeben werden, sortiert Binder das Argumentarray neu, und dies wird dem Aufrufer angezeigt.When arguments are passed by name, Binder reorders the argument array, and that is what the caller sees. Weitere Informationen finden Sie unter Binder.ReorderArgumentArray.For more information, see Binder.ReorderArgumentArray.

Die Menge der verfügbaren Member sind diejenigen, die im Typ oder einem Basistyp definiert.The set of available members are those members defined in the type or any base type. Wenn BindingFlags angegeben wird, werden Member aller Zugriffsebenen in den Satz zurückgegeben.If BindingFlags is specified, members of any accessibility will be returned in the set. Wenn BindingFlags.NonPublic nicht angegeben wird, muss der Binder die Zugriffsregeln erzwingen.If BindingFlags.NonPublic is not specified, the binder must enforce accessibility rules. Wenn die Bindungsflags Public oder NonPublic angegeben werden, müssen Sie auch die Bindungsflags Instance oder Static angeben. Andernfalls werden keine Member zurückgegeben.When specifying the Public or NonPublic binding flag, you must also specify the Instance or Static binding flag, or no members will be returned.

Wenn nur ein Member mit dem angegebenen Namen verfügbar ist, ist kein Rückruf notwendig, und die Bindung wird auf der Methode ausgeführt.If there is only one member of the given name, no callback is necessary, and binding is done on that method. Fall 1 des Codebeispiels veranschaulicht dies: Hier ist nur eine PrintBob-Methode verfügbar, und daher ist kein Rückruf erforderlich.Case 1 of the code example illustrates this point: Only one PrintBob method is available, and therefore no callback is needed.

Wenn sich mehr als ein Member im verfügbaren Satz befindet, werden alle diese Methoden an BindToMethod übergeben, das die richtige Methode ausgewählt und sie zurückgibt.If there is more than one member in the available set, all these methods are passed to BindToMethod, which selects the appropriate method and returns it. Bei Fall 2 des Codebeispiels gibt es zwei Methoden namens PrintValue.In Case 2 of the code example, there are two methods named PrintValue. Die geeignete Methode wird über einen Aufruf von BindToMethod ausgewählt.The appropriate method is selected by the call to BindToMethod.

ChangeType führt die Argumentkoersion (Typkonvertierung) aus, die die eigentlichen Argumente in den Typ der formalen Argumente der ausgewählten Methode konvertiert.ChangeType performs argument coercion (type conversion), which converts the actual arguments to the type of the formal arguments of the selected method. ChangeType wird für jedes Argument aufgerufen, selbst wenn die Typen exakt übereinstimmen.ChangeType is called for every argument even if the types match exactly.

In Fall 3 des Codebeispiels wird ein Argument des Typs String mit dem Wert „5,5“ an eine Methode mit einem formalen Argument vom Typ Double übergeben.In Case 3 of the code example, an actual argument of type String with a value of "5.5" is passed to a method with a formal argument of type Double. Damit der Aufruf erfolgreich ausgeführt werden kann, muss der Zeichenfolgenwert „5,5“ in einen Double-Wert konvertiert werden.For the invocation to succeed, the string value "5.5" must be converted to a double value. Für diese Konvertierung ist ChangeType zuständig.ChangeType performs this conversion.

ChangeType führt nur verlustfreie oder Erweiterungsumwandlungen aus, wie in der folgenden Tabelle dargestellt.ChangeType performs only lossless or widening coercions, as shown in the following table.

QuelltypSource type ZieltypTarget type
Beliebiger TypAny type Dessen BasistypIts base type
Beliebiger TypAny type Die implementierte SchnittstelleInterface it implements
CharChar UInt16, UInt32, Int32, UInt64, Int64, Single, DoubleUInt16, UInt32, Int32, UInt64, Int64, Single, Double
ByteByte Char, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, DoubleChar, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, Double
SByteSByte Int16, Int32, Int64, Single, DoubleInt16, Int32, Int64, Single, Double
UInt16UInt16 UInt32, Int32, UInt64, Int64, Single, DoubleUInt32, Int32, UInt64, Int64, Single, Double
Int16Int16 Int32, Int64, Single, DoubleInt32, Int64, Single, Double
UInt32UInt32 UInt64, Int64, Single, DoubleUInt64, Int64, Single, Double
Int32Int32 Int64, Single, DoubleInt64, Single, Double
UInt64UInt64 Single, DoubleSingle, Double
Int64Int64 Single, DoubleSingle, Double
SingleSingle DoubleDouble
NichtverweistypNonreference type VerweistypReference type

Die Type-Klasse verfügt über Get-Methoden, die Parameter des Typs Binder nutzen, um Verweise auf einen bestimmten Member aufzulösen.The Type class has Get methods that use parameters of type Binder to resolve references to a particular member. Type.GetConstructor, Type.GetMethod, und Type.GetProperty suchen nach einem bestimmten Member des aktuellen Typs, indem sie die Signaturinformationen für diesen Member zur Verfügung stellen.Type.GetConstructor, Type.GetMethod, and Type.GetProperty search for a particular member of the current type by providing signature information for that member. Binder.SelectMethod und Binder.SelectProperty werden wieder aufgerufen, um die jeweiligen Signaturinformationen der geeigneten Methoden auszuwählen.Binder.SelectMethod and Binder.SelectProperty are called back on to select the given signature information of the appropriate methods.

Siehe auchSee also