مشاركة عبر


تحميله ديناميكياً و استخدام أنواع

انعكاس provides infrastructure used بواسطة اللغة compilers such كـ Microsoft Visual Basic 2005 و JScript إلى implement implicit ربط في وقت التشغيل. ربط هو the عملية of locating the إعلان (that هو, the implementation) that corresponds إلى a uniquely specified نوع. عند ترتيب هو تحدث عملية في وقت التشغيل بدلاً من وقت التحويل البرمجي، هو تسمى ربط في وقت التشغيل. Visual Basic 2005يسمح لك إلى استخدام ربط المتأخر ضمني في تعليمات برمجية الخاصة بك؛ المحول البرمجي Visual أساسى استدعاء أسلوب مساعد الذي يستخدم انعكاس إلى الحصول على نوع كائن. الوسائط التي تم تمريرها إلى المساعد أسلوب تسبب المناسبة أسلوب لطلبة في وقت التشغيل. These الوسيطات are the مثيل (an كائن) تشغيل which إلى invoke the أسلوب, the اسم of the invoked أسلوب (a سلسلة), و the الوسيطات passed إلى the invoked أسلوب (an مصفوفه من الكائنات).

في the following مثال, the Visual أساسى compiler uses انعكاس ضمنيا إلى يتصل a أسلوب تشغيل an كائن whose نوع ليس known at يحول برمجياً الوقت. A HelloWorld فئة has a PrintHello أسلوب that prints خارج "Hello World" concatenated مع some نص that هو passed إلى the PrintHello أسلوب. الأسلوب PrفيtHello الذي يسمى في هذا المثال هو فعلياً على Type.InvokeMember; يسمح تعليمات برمجية Visual أساسى PrفيtHello الأسلوب طلبه كما لو كانت تعرف نوع الكائن (helloObj) في وقت التحويل البرمجي (ربط المبكر) وليس في وقت التشغيل (متأخر ربط).

Imports System
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

مخصص ربط

في addition إلى being used ضمنيا بواسطة compilers for ربط في وقت التشغيل, انعكاس can be used بوضوح في تعليمات برمجية إلى accomplish ربط في وقت التشغيل.

The وقت تشغيل اللغة العامة supports multiple programming languages, و the ربط rules of these languages differ. في the early-حدود حالة, تعليمات برمجية generators can completely عنصر تحكم this ربط. However, في ربط في وقت التشغيل through انعكاس, binding must be controlled بواسطة مخصص binding. The Binder فئة provides مخصص عنصر تحكم of عضو تحديد و invocation.

Using مخصص ربط, you can تحميل an تجميع at run الوقت, obtain معلومات حول أنواع في that تجميع, specify the نوع that you want, و then invoke وظائف أو الوصول حقول أو خصائص تشغيل that نوع. This technique هو useful if you do not know an كائن's نوع at يحول برمجياً الوقت, such كـ when the كائن نوع هو dependent تشغيل مستخدم إدخال.

The following مثال demonstrates a simple مخصص binder that provides لا وسيطة نوع تحويل. تعليمات برمجية for Simple_Type.dll precedes the main مثال. Be sure إلى بنية Simple_Type.dll و then تضمين a مرجع إلى it في the مشروع at بنية الوقت.

' Code for building Simple_Type.dll.
Imports System

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

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

Imports System
Imports System.Reflection
Imports System.Globalization
Imports Simple_Type.Simple_Type

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 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 'Main
    End Class 'MyMainClass

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

        Public Overrides Function BindToMethod(ByVal bindingAttr As 
            BindingFlags, ByVal match() As MethodBase, ByRef args() As 
                Object, ByVal modifiers() As ParameterModifier, ByVal 
                    culture As CultureInfo, ByVal 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.
            Dim mb As MethodBase
            For Each mb In match
                Dim parameters As ParameterInfo() = mb.GetParameters()
                If ParametersMatch(parameters, args) Then
                    Return mb
                End If
            Next mb
            Return Nothing
        End Function 'BindToMethod

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

        Public Overrides Function SelectMethod(ByVal bindingAttr As 
            BindingFlags, ByVal match() As MethodBase, ByVal types() As 
                Type, ByVal 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.
            Dim mb As MethodBase
            For Each mb In match
                Dim parameters As ParameterInfo() = mb.GetParameters()
                If ParametersMatch(parameters, types) Then
                    Return mb
                End If
            Next mb
            Return Nothing
        End Function 'SelectMethod

        Public Overrides Function SelectProperty(ByVal bindingAttr As 
            BindingFlags, ByVal match() As PropertyInfo, ByVal returnType 
                As Type, ByVal indexes() As Type, ByVal modifiers() As 
                    ParameterModifier) As PropertyInfo
            If match Is Nothing Then
                Throw New ArgumentNullException("match")
            End If
            Dim pi As PropertyInfo
            For Each pi In match
                If pi.GetType() Is returnType And 
                    ParametersMatch(pi.GetIndexParameters(), indexes) Then
                    Return pi
                End If
            Next pi
            Return Nothing
        End Function 'SelectProperty

        Public Overrides Function ChangeType(ByVal value As Object, 
            ByVal myChangeType As Type, ByVal 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
            End Try
        End Function 'ChangeType

        Public Overrides Sub ReorderArgumentArray(ByRef args() As Object, 
            ByVal 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 'ReorderArgumentArray

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

        ' Returns true only if the type of each object in a matches
        ' the type of each corresponding entry in b.
        Private Overloads Function ParametersMatch(ByVal a() As 
            ParameterInfo, ByVal b() As Type) As Boolean
            If a.Length <> b.Length Then
                Return False
            End If
            Dim i As Integer
            For i = 0 To a.Length - 1
                If Not (a(i).ParameterType Is b(i)) Then
                    Return False
                End If
            Next i
            Return True
        End Function 'ParametersMatch
    End Class 'MyCustomBinder
End Namespace 'Custom_Binder


// Code for building SimpleType.dll.
using System;

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);
        }
    }
}


using System;
using System.Reflection;
using System.Globalization;
using Simple_Type;
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;
        }
    }
}

InvokeMember و CreateInstance

استخدم Type.InvokeMember إلى invoke a عضو of a نوع. The CreateInstance وظائف of متنوع فئات, such كـ النظام.Activator و النظام.انعكاس.تجميع, are specialized forms of InvokeMember that إنشاء ارتباط جديد instances of the specified نوع. The Binder فئة هو used for التحميل الزائد دقة و وسيطة coercion في these وظائف.

يظهر المثال التالي التركيبات الممكنة الثلاثة من قسرية وسيطة (نوع تحويل) و تحديد الأعضاء. في "الحالة الأولى" أو لا تحديد عضو أو قسرية وسيطة هو المطلوبة. في "الحالة الثانية"، وتحديد الأعضاء فقط هو المطلوبة. في حالة 3، قسرية وسيطة فقط هو المطلوبة.

public class CustomBinderDriver
{
    public static void Main (string[] arguments)
    {
    Type t = typeof (CustomBinderDriver);
    CustomBinder binder = new CustomBinder();
    BindingFlags flags = BindingFlags.InvokeMethod|BindingFlags.Instance|
        BindingFlags.Public|BindingFlags.Static;

    // 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);
    }
}

حل زيادة التحميل هو الحاجة لوقت المزيد عضو واحد يحمل نفس الاسم هو المتوفرة. Binder.BindToMethodو Binder.BindToFieldالأساليب إلى حل ربط إلى عضو مفرد. Binder.BindToMethod أيضا توفير تحليل خاصية من خلال يحصل و التعيين accessors خاصية.

BindToMethod بإرجاع MethodBaseلاستدعاء، أو مرجع فارغ ( لا شيء في Vهوual أساسي) في حالة عدم وجود مثل هذا الاستدعاء هو المحتملة. من MethodBase بإرجاع يجب إلا تكون القيمة واحدة من تلك الموجودة في معلمة يطابق ، على الرغم من أن الذي هو الحالة العادية.

في حالة وجود وسيطات ByRef، قد تحتاج المتصل إلى لاسترداد. ولذلك، يسمح أوراق عميل لتعيين صفيفة الوسيطات الخلف إلى شكلها الأصلي إذا تم معالجته من BindToMethod صفيفة وسيطة. لكي تتمكن من القيام بترتيب هو، يجب أن يكون الطالب يمكن ضمان ترتيب الوسيطات هو بدون تغيير. حيث يتم تمرير الوسيطات حسب الاسم، reorders أوراق صفيفة وسيطة، وأن هو ما يراه الشخص المتصل. لمزيد من المعلومات، راجع Binder.ReorderArgumentArray.

مجموعة الأعضاء المتاحين قابلة لأعضاء تلك المعرفة في النوع أو أي الأساس نوع. إذا من BindingFlags.NonPublic هو، الأعضاء من أي وصول ذوي الاحتياجات الخاصة سيتم إرجاع في المجموعة. إذا من BindingFlags.NonPublic هو لم يكن محدداً، الموثق يجب فرض قواعد وصول ذوي الاحتياجات الخاصة. عند تحديد العام أو لا nPublic إشارة ربط ، يجب أيضا تحديد مثيل أو ثابتة التوثيق إشارة، أو لا سيتم إرجاع الأعضاء.

إذا كان هناك واحد فقط عضو في هذا الاسم، رد الاتصال غير ضروري، ويتم إجراء ربط تشغيل هذه الطريقة. حالة 1 تعليمات برمجية مثال يوضح هذه النقطة: واحد فقط PrintBob الطريقة هو المتوفرة، ولذلك لا يوجد رد هو المطلوبة.

إذا كان هناك هو أكثر من عضو في مجموعة متوفرة، يتم تمرير الجميع هذه الأساليب إلى BindToMethod ، الذي يحدد الطريقة المناسبة وإرجاعه. في "الحالة الثانية" من تعليمات برمجية المثال، توجد طريقتان باسم من PrintValue. الطريقة المناسبة هو المحددة من قبل الاستدعاء من BindToMethod.

ChangeTypeينفذ قسرية وسيطة (تحويل نوع)، والتي تقوم بتحويل الوسيطات الفعلية إلى نوع وسيطة رسمية للأسلوب المحدد. ChangeType هو استدعاء لكل وسيطة حتى في حالة تطابق الأنواع تماما.

في حالة كتابة 3 لمثال التعليمة البرمجية، وسيطة فعلية من سلسلةتحتوي على القيمة "5.5" هو الذي تم تمريره إلى أسلوب باستخدام وسيطة رسمية من نوع نوع بيانات مزدوج. الاستدعاء نجاح، يجب محول القيمة السلسلة "5.5" إلى القيمة مزدوجة. ChangeType تنفيذ هذا تحويل.

ChangeType ينفذ فقط بدون فقدان بيانات أو توسيع coercions ، كما هو موضح في الجدول التالي.

نوع المصدر

نوع الهدف

أي نوع

به أساس نوع

أي نوع

واجهة implements

حرف

UInt16 UInt32، Int32 أو UInt64، Int64، مفرد، مزدوج

Byte (بايت)

مفرد حرف، UInt16، Int16، UInt32، Int32، UInt64، Int64،، مزدوج

SByte

Int16، Int32، Int64، مفرد، مزدوج

UInt16

UInt32 Int32 أو UInt64، Int64، مفرد، مزدوج

Int16

Int32، Int64، مفرد، مزدوج

UInt32

UInt64، Int64، مفرد، مزدوج

Int32

Int64، مفرد، مزدوج

UInt64

مفرد، مزدوج

Int64

مفرد، مزدوج

مفرد

مزدوج

نوع nonreference

نوع المرجع

Typeلدى فئة يحصل وظائف التي تستخدم المعلمات من نوع أوراق لحل المراجع إلى عضو محدد. Type.GetConstructor,Type.GetMethod، وType.GetPropertyبحث عن عضو معين من النوع الحالي بواسطة توفير معلومات توقيع لهذا العضو. Binder.SelectMethod and Binder.SelectProperty are called back on to select the given signature information of the appropriate methods.

راجع أيضًا:

المرجع

Type.InvokeMember

Assembly.Load

المبادئ

عرض معلومات نوع

تحويل نوع في .NET Framework