Carregando e usando tipos dinamicamenteDynamically Loading and Using Types

A reflexão fornece a infraestrutura usada pelos compiladores de linguagem para implementar a associação tardia implícita.Reflection provides infrastructure used by language compilers to implement implicit late binding. Associação é o processo de localizar a declaração (ou seja, a implementação) que corresponde a um tipo especificado exclusivamente.Binding is the process of locating the declaration (that is, the implementation) that corresponds to a uniquely specified type. Quando esse processo ocorre no tempo de execução em vez do tempo de compilação, ele é chamado de associação tardia.When this process occurs at run time rather than at compile time, it is called late binding. O Visual Basic permite que você use associação tardia implícita em seu código. O compilador do Visual Basic chama um método auxiliar que usa a reflexão para obter o tipo de objeto.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. Os argumentos passados para o método auxiliar fazem com que o método apropriado seja invocado no tempo de execução.The arguments passed to the helper method cause the appropriate method to be invoked at run time. Esses argumentos são a instância (um objeto) na qual o método será invocado, o nome do método invocado (uma cadeia de caracteres) e os argumentos passados para o método invocado (uma matriz de objetos).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).

No exemplo a seguir, o compilador do Visual Basic usa reflexão implicitamente para chamar um método em um objeto cujo tipo não é conhecido no tempo de compilação.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. Uma classe HelloWorld tem um método PrintHello que imprime “Hello World” concatenado com algum texto que é passado para o método PrintHello.A HelloWorld class has a PrintHello method that prints out "Hello World" concatenated with some text that is passed to the PrintHello method. O método PrintHello chamado neste exemplo é na verdade um Type.InvokeMember; o código do Visual Basic permite que o método PrintHello seja invocado como se o tipo de objeto (helloObj) fosse conhecido durante o tempo de compilação (associação antecipada) em vez de no tempo de execução (associação tardia).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  

Associação personalizadoCustom Binding

Além de ser usado implicitamente por compiladores para associação tardia, a reflexão pode ser usada explicitamente no código para realizar a associação tardia.In addition to being used implicitly by compilers for late binding, reflection can be used explicitly in code to accomplish late binding.

O Common Language Runtime dá suporte a várias linguagens de programação e as regras de associação dessas linguagens são diferentes.The common language runtime supports multiple programming languages, and the binding rules of these languages differ. No caso de associação antecipada, os geradores de código podem controlar essa associação completamente.In the early-bound case, code generators can completely control this binding. No entanto, na associação tardia por meio de reflexão, a associação deve ser controlada pela associação personalizada.However, in late binding through reflection, binding must be controlled by customized binding. A classe Binder fornece controle personalizado do membro de seleção e da invocação.The Binder class provides custom control of member selection and invocation.

Usando a associação personalizada, você pode carregar um assembly no tempo de execução, obter informações sobre tipos nesse assembly, especificar o tipo que você deseja e, em seguida, invocar métodos ou acessar campos ou propriedades nesse tipo.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. Essa técnica é útil se você não souber o tipo de um objeto no tempo de compilação, como quando o tipo de objeto depende da entrada do usuário.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.

O exemplo a seguir demonstra um associador personalizado simples que não fornece nenhuma conversão de tipo de argumento.The following example demonstrates a simple custom binder that provides no argument type conversion. O código de Simple_Type.dll precede o exemplo principal.Code for Simple_Type.dll precedes the main example. Verifique se você compilou Simple_Type.dll e incluiu uma referência a ele no projeto no tempo de compilação.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 e CreateInstanceInvokeMember and CreateInstance

Use Type.InvokeMember para invocar um membro de um tipo.Use Type.InvokeMember to invoke a member of a type. Os métodos CreateInstance de várias classes, como Activator.CreateInstance e Assembly.CreateInstance, são formas especializadas de InvokeMember que criam novas instâncias do tipo especificado.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. A classe Binder é usada para resolução de sobrecarga e coerção de argumento nesses métodos.The Binder class is used for overload resolution and argument coercion in these methods.

O exemplo a seguir mostra três combinações possíveis de coerção de argumento (conversão de tipo) e seleção de membro.The following example shows the three possible combinations of argument coercion (type conversion) and member selection. No caso 1, não é necessária nenhuma coerção de argumento ou seleção de membro.In Case 1, no argument coercion or member selection is needed. No caso 2, somente a seleção de membro é necessária.In Case 2, only member selection is needed. No caso 3, somente a coerção de argumento é necessária.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

A resolução de sobrecarga é necessária quando mais de um membro com o mesmo nome está disponível.Overload resolution is needed when more than one member with the same name is available. Os métodos Binder.BindToMethod e Binder.BindToField são usados para resolver a associação para um único membro.The Binder.BindToMethod and Binder.BindToField methods are used to resolve binding to a single member. O Binder.BindToMethod também fornece a resolução de propriedade por meio de dos acessadores de propriedade get e set.Binder.BindToMethod also provides property resolution through the get and set property accessors.

O BindToMethod retorna o MethodBase a ser invocado ou uma referência nula (Nothing no Visual Basic) se tal invocação não for possível.BindToMethod returns the MethodBase to invoke, or a null reference (Nothing in Visual Basic) if no such invocation is possible. O valor retornado de MethodBase não precisa ser um dos contidos no parâmetro match, embora isso seja o comum.The MethodBase return value need not be one of those contained in the match parameter, although that is the usual case.

Quando houver argumentos ByRef, o chamador poderá tentar recuperá-los.When ByRef arguments are present, the caller might want to get them back. Portanto, Binder permite a um cliente mapear a matriz de argumentos para sua forma original se BindToMethod tiver manipulado a matriz de argumento.Therefore, Binder allows a client to map the array of arguments back to its original form if BindToMethod has manipulated the argument array. Para fazer isso, é necessário garantir ao chamador que a ordem dos argumentos se mantém inalterada.In order to do this, the caller must be guaranteed that the order of the arguments is unchanged. Quando os argumentos são passados por nome, o Binder reorganiza a matriz de argumentos e é isso que o chamador vê.When arguments are passed by name, Binder reorders the argument array, and that is what the caller sees. Para obter mais informações, consulte Binder.ReorderArgumentArray.For more information, see Binder.ReorderArgumentArray.

O conjunto de membros disponíveis aqueles definidos no tipo ou em qualquer tipo base.The set of available members are those members defined in the type or any base type. Se BindingFlags for especificado, membros de qualquer acessibilidade serão retornados ao conjunto.If BindingFlags is specified, members of any accessibility will be returned in the set. Se BindingFlags.NonPublic não for especificado, o associador deverá impor regras de acessibilidade.If BindingFlags.NonPublic is not specified, the binder must enforce accessibility rules. Ao especificar o sinalizador de associação Public ou NonPublic, você deverá especificar também o sinalizador de associação Instance ou Static ou nenhum membro será retornado.When specifying the Public or NonPublic binding flag, you must also specify the Instance or Static binding flag, or no members will be returned.

Se houver somente um membro do nome fornecido, nenhum retorno de chamada é necessário e a associação é realizada nesse método.If there is only one member of the given name, no callback is necessary, and binding is done on that method. O caso 1 do exemplo de código ilustra este ponto: apenas um método PrintBob está disponível e, portanto, nenhum retorno de chamada é necessário.Case 1 of the code example illustrates this point: Only one PrintBob method is available, and therefore no callback is needed.

Se houver mais de um membro do conjunto disponível, todos esses métodos são passados para BindToMethod, que seleciona o método apropriado e o retorna.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. No caso 2 do exemplo de código, há dois métodos chamados PrintValue.In Case 2 of the code example, there are two methods named PrintValue. O método apropriado é selecionado pela chamada para BindToMethod.The appropriate method is selected by the call to BindToMethod.

O ChangeType executa a coerção de argumento (conversão de tipo), que converte os argumentos reais para o tipo dos argumentos formais do método selecionado.ChangeType performs argument coercion (type conversion), which converts the actual arguments to the type of the formal arguments of the selected method. ChangeType é chamado para cada argumento, mesmo se os tipos de corresponderem exatamente.ChangeType is called for every argument even if the types match exactly.

No caso 3 do exemplo de código, um argumento real do tipo String com um valor de “5.5” é passado para um método com um argumento formal do tipo Double.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. Para que a invocação seja bem-sucedida, o valor da cadeia de caracteres “5.5” deve ser convertido em um valor duplo.For the invocation to succeed, the string value "5.5" must be converted to a double value. O ChangeType executa essa conversão.ChangeType performs this conversion.

O ChangeType executa apenas coerções de expansão ou sem perdas, conforme mostrado na tabela a seguir.ChangeType performs only lossless or widening coercions, as shown in the following table.

Tipo de origemSource type Tipo de destinoTarget type
Qualquer tipoAny type O tipo baseIts base type
Qualquer tipoAny type Interface implementadaInterface it implements
CharChar UInt16, UInt32, Int32, UInt64, Int64, Single e DoubleUInt16, UInt32, Int32, UInt64, Int64, Single, Double
ByteByte Char, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single e DoubleChar, UInt16, Int16, UInt32, Int32, UInt64, Int64, Single, Double
SByteSByte Int16, Int32, Int64, Single e DoubleInt16, Int32, Int64, Single, Double
UInt16UInt16 UInt32, Int32, UInt64, Int64, Single e DoubleUInt32, Int32, UInt64, Int64, Single, Double
Int16Int16 Int32, Int64, Single e DoubleInt32, Int64, Single, Double
UInt32UInt32 UInt64, Int64, Single e DoubleUInt64, Int64, Single, Double
Int32Int32 Int64, Single e DoubleInt64, Single, Double
UInt64UInt64 Single, DoubleSingle, Double
Int64Int64 Single, DoubleSingle, Double
SingleSingle DoubleDouble
Tipo NonreferenceNonreference type Tipo de referênciaReference type

A classe Type tem métodos Get que usam parâmetros do tipo Binder para resolver referências a um determinado membro.The Type class has Get methods that use parameters of type Binder to resolve references to a particular member. Type.GetConstructor, Type.GetMethod e Type.GetProperty pesquisam um determinado membro do tipo atual, fornecendo informações de assinatura para esse membro.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 e Binder.SelectProperty são chamados de volta para selecionar as informações de determinada assinatura dos métodos apropriados.Binder.SelectMethod and Binder.SelectProperty are called back on to select the given signature information of the appropriate methods.

Consulte tambémSee also