مشاركة عبر


كيفية القيام بما يلي: قم بفحص و إنشاء مثيل لأنواع عامة مع انعكاس

معلومات حول الأنواع العامة هو الحصول عليها بنفس الطريقة كمعلومات حول أنواع غير ذلك: بواسطة فحص Typeكائن الذي يمثل نوع عام. الفرق الأساسي هو أن يحتوي نوع عام lهوt Typeالكائنات التي تمثل لها معلمات نوع عام. يفحص إجراء أول في هذا القسم العام أنواع.

يمكنك إنشاء Typeكائن الذي يمثل نوع constructed بوسيطات نوع ربط إلى نوع المعلمات لتعريف نوع عام. يوضح إجراء الثاني هذا.

إلى فحص نوع عام ومعلمات النوع الخاص به

  1. يحصل مثيل Typeالذي يمثل نوع عام. في التعليمة البرمجية التالية، والنوع هو الحصول عليها باستخدام C# typeofعامل التشغيل ( GetTypeفي Vهوual أساسي typeidفي C + + Vهوual). راجع Typeإلى صورة عن طرق غير ذلك لفئة إلى الحصول على Typeالكائن. لاحظ أنه في بقية th هو إجراء والنوع هو في معلمة أسلوب يسمى t.

    Dim d1 As Type = GetType(Dictionary(Of ,))
    
    Type d1 = typeof(Dictionary<,>);
    
  2. استخدام IsGenericTypeخاصية لتحديد ما إذا كان النوع هو العام، واستخدام IsGenericTypeDefinitionخاصية لتحديد ما إذا كان النوع هو تعريف نوع عام.

    Console.WriteLine("   Is this a generic type? " _ 
        & t.IsGenericType)
    Console.WriteLine("   Is this a generic type definition? " _ 
        & t.IsGenericTypeDefinition)
    
    Console.WriteLine("   Is this a generic type? {0}",
        t.IsGenericType);
    Console.WriteLine("   Is this a generic type definition? {0}",
        t.IsGenericTypeDefinition);
    
  3. يحصل صفيفة يحتوي على وسيطات نوع عام، باستخدام GetGenericArgumentsأسلوب.

    Dim typeParameters() As Type = t.GetGenericArguments()
    
    Type[] typeParameters = t.GetGenericArguments();
    
  4. لكل وسيطة نوع، قم بتحديد ما إذا كان ذلك هو معلمة نوع (على سبيل المثال، في تعريف نوع عام) أو نوع تم تحديده لمعلمة نوع (على سبيل المثال، في نوع constructed)، استخدام IsGenericParameterخاصية.

    Console.WriteLine("   List {0} type arguments:", _
        typeParameters.Length)
    For Each tParam As Type In typeParameters
        If tParam.IsGenericParameter Then
            DisplayGenericParameter(tParam)
        Else
            Console.WriteLine("      Type argument: {0}", _
                tParam)
        End If
    Next
    
    Console.WriteLine("   List {0} type arguments:", 
        typeParameters.Length);
    foreach( Type tParam in typeParameters )
    {
        if (tParam.IsGenericParameter)
        {
            DisplayGenericParameter(tParam);
        }
        else
        {
            Console.WriteLine("      Type argument: {0}",
                tParam);
        }
    }
    
  5. في الالنظام نوع عام اكتب المعلمة هو يمثله مثيل Type، فقط كانا الأنواع العادية. عرض تعليمات برمجية التالية موضع اسم والمعلمة Typeكائن التي تمثل معلمة نوع عام. موضع المعلمة هو المعلومات العادية هنا؛ هو من أكثر فائدة عند التي يتم اختبار معلمة نوع تم استخدامه كوسيطة نوع من نوع عام آخر.

    Private Shared Sub DisplayGenericParameter(ByVal tp As Type)
        Console.WriteLine("      Type parameter: {0} position {1}", _
            tp.Name, tp.GenericParameterPosition)
    
    private static void DisplayGenericParameter(Type tp)
    {
        Console.WriteLine("      Type parameter: {0} position {1}", 
            tp.Name, tp.GenericParameterPosition);
    
  6. حدد قيد النوع الأساسي والقيود الموجودة على واجهة لمعلمة نوع عام باستخدام GetGenericParameterConstraintsأسلوب إلى الحصول على الجميع القيود الموجودة في صفيفة مفرد. قيود لا يمكن ضمان إلى في أي ترتيب معين.

    Dim classConstraint As Type = Nothing
    
    For Each iConstraint As Type In tp.GetGenericParameterConstraints()
        If iConstraint.IsInterface Then
            Console.WriteLine("         Interface constraint: {0}", _
                iConstraint)
        End If
    Next
    
    If classConstraint IsNot Nothing Then
        Console.WriteLine("         Base type constraint: {0}", _
            tp.BaseType)
    Else
        Console.WriteLine("         Base type constraint: None")
    End If
    
    Type classConstraint = null;
    
    foreach(Type iConstraint in tp.GetGenericParameterConstraints())
    {
        if (iConstraint.IsInterface)
        {
            Console.WriteLine("         Interface constraint: {0}",
                iConstraint);
        }
    }
    
    if (classConstraint != null)
    {
        Console.WriteLine("         Base type constraint: {0}", 
            tp.BaseType);
    }
    else
        Console.WriteLine("         Base type constraint: None"); 
    
  7. استخدام GenericParameterAttributesخاصية اكتشاف خاص القيود تشغيل معلمة نوع، مثل التي تتطلب أن يكون النوع المرجع. يشتمل قيم التي تمثل التباين، يمكنك mكـk إيقاف تشغيل خاصية كـ في التعليمة البرمجية التالية.

    Dim sConstraints As GenericParameterAttributes = _
        tp.GenericParameterAttributes And _
        GenericParameterAttributes.SpecialConstraintMask
    
    GenericParameterAttributes sConstraints = 
        tp.GenericParameterAttributes & 
        GenericParameterAttributes.SpecialConstraintMask;
    
  8. السمات خاص قيد هي العلامات، و نفس يؤشر ( GenericParameterAttributes.None) الذي يمثل خاص لا توجد قيود يشير عدم وجود التباين المشترك أو contravariance. وهكذا، إلى اختبار لأي من هذه الشروط التي يجب أن يستخدم القناع المناسب. في هذه الحالة، استخدم GenericParameterAttributes.SpecialConstraintMaskإلى عزل علامات الخاصة بالقيد.

    If sConstraints = GenericParameterAttributes.None Then
        Console.WriteLine("         No special constraints.")
    Else
        If GenericParameterAttributes.None <> (sConstraints And _
            GenericParameterAttributes.DefaultConstructorConstraint) Then
            Console.WriteLine("         Must have a parameterless constructor.")
        End If
        If GenericParameterAttributes.None <> (sConstraints And _
            GenericParameterAttributes.ReferenceTypeConstraint) Then
            Console.WriteLine("         Must be a reference type.")
        End If
        If GenericParameterAttributes.None <> (sConstraints And _
            GenericParameterAttributes.NotNullableValueTypeConstraint) Then
            Console.WriteLine("         Must be a non-nullable value type.")
        End If
    End If
    
    if (sConstraints == GenericParameterAttributes.None)
    {
        Console.WriteLine("         No special constraints.");
    }
    else
    {
        if (GenericParameterAttributes.None != (sConstraints &
            GenericParameterAttributes.DefaultConstructorConstraint))
        {
            Console.WriteLine("         Must have a parameterless constructor.");
        }
        if (GenericParameterAttributes.None != (sConstraints &
            GenericParameterAttributes.ReferenceTypeConstraint))
        {
            Console.WriteLine("         Must be a reference type.");
        }
        if (GenericParameterAttributes.None != (sConstraints &
            GenericParameterAttributes.NotNullableValueTypeConstraint))
        {
            Console.WriteLine("         Must be a non-nullable value type.");
        }
    }
    

بناء مثيل لعام نوع

نوع عام هو كقالب. لا يمكن إنشاء مثيلات عليه ما لم يتم تحديد أنواع الحقيقية الخاصة بها عام معلمات نوع. إلى بذلك في وقت التشغيل، استخدام الانعكاس، يتطلب MakeGenericTypeالأسلوب.

لإنشاء مثيل عام نوع

  1. يحصل Typeكائن الذي يمثل نوع عام. إحضار تعليمات برمجية التالية نوع عام Dictionary<TKey, TValue>في الثاني طرق مختلفة: باستخدام Type.GetType(String)التحميل الزائد للأسلوب بسلسلة تصف النوع، و عن طريق استدعاء GetGenericTypeDefinitionالأسلوب تشغيل نوع constructed Dictionary<String, Example>(Dictionary(Of String, Example)في Visual أساسى). MakeGenericTypeأسلوب يتطلب تعريف نوع عام.

    ' Use the GetType operator to create the generic type 
    ' definition directly. To specify the generic type definition,
    ' omit the type arguments but retain the comma that separates
    ' them.
    Dim d1 As Type = GetType(Dictionary(Of ,))
    
    ' You can also obtain the generic type definition from a
    ' constructed class. In this case, the constructed class
    ' is a dictionary of Example objects, with String keys.
    Dim d2 As New Dictionary(Of String, Example)
    ' Get a Type object that represents the constructed type,
    ' and from that get the generic type definition. The 
    ' variables d1 and d4 contain the same type.
    Dim d3 As Type = d2.GetType()
    Dim d4 As Type = d3.GetGenericTypeDefinition()
    
    // Use the typeof operator to create the generic type 
    // definition directly. To specify the generic type definition,
    // omit the type arguments but retain the comma that separates
    // them.
    Type d1 = typeof(Dictionary<,>);
    
    // You can also obtain the generic type definition from a
    // constructed class. In this case, the constructed class
    // is a dictionary of Example objects, with String keys.
    Dictionary<string, Example> d2 = new Dictionary<string, Example>();
    // Get a Type object that represents the constructed type,
    // and from that get the generic type definition. The 
    // variables d1 and d4 contain the same type.
    Type d3 = d2.GetType();
    Type d4 = d3.GetGenericTypeDefinition();
    
  2. إنشاء صفيفة من نوع الوسيطات إلى استبدال لنوع المعلمات. يجب أن يحتوي الصفيف على العدد الصحيح من Typeعلى الكائنات، بنفس الترتيب الذي تظهر به في القائمة نوع معلمة. في هذه الحالة، المفتاح (معلمة النوع أول) من نوع String، و قيم الموجودة في القاموس مثيلات فئة ما يسمى Example.

    Dim typeArgs() As Type = _
        { GetType(String), GetType(Example) }
    
    Type[] typeArgs = {typeof(string), typeof(Example)};
    
  3. باستدعاء MakeGenericTypeأسلوب إلى يربط الوسيطات نوع إلى معلمات نوع وبناء نوع.

    Dim constructed As Type = _
        d1.MakeGenericType(typeArgs)
    
    Type constructed = d1.MakeGenericType(typeArgs);
    
  4. استخدام CreateInstance(Type)أسلوب زيادة التحميل لإنشاء كائن من النوع constructed. يخزن تعليمات برمجية التالية مثيلين من Exampleالفئة في الناتج عن عملية الدمج Dictionary<String, Example>الكائن.

    Dim o As Object = Activator.CreateInstance(constructed)
    
    object o = Activator.CreateInstance(constructed);
    

مثال

مثال التعليمة البرمجية التالية بتعريف DisplayGenericTypeالأسلوب لفحص بملفات تعريف النوع العام وبناء أنواع المستخدمة في تعليمات برمجية وعرض المعلومات الخاصة بها. DisplayGenericTypeالعروض أسلوب كيف إلى استخدام IsGenericType، IsGenericParameter، و GenericParameterPositionالخصائص و GetGenericArgumentsالأسلوب.

المثال كما يعرف DisplayGenericParameterأسلوب إلى فحص معلمة نوع عام وعرض القيود الخاصة بها.

مثال التعليمة البرمجية بتعريف التعيين من أنواع الاختبار، بما في ذلك نوع عام يقوم بتوضيح اكتب القيود معلمة وإظهار كيفية إلى عرض معلومات حول هذه الأنواع.

المثال بناء على نوع من Dictionary<TKey, TValue>الفئة بواسطة إنشاء صفيفة من نوع الوسيطات و استدعاء MakeGenericTypeالأسلوب. برنامج مقارنة Typeالكائن بناء استخدام MakeGenericTypeمع (Typeفي Visual أساسى) ، demonstrating بأنها نفس.typeofالحصول عليها باستخدام كائنGetType وبالمثل، يستخدم البرنامج GetGenericTypeDefinitionطريقة للحصول على العام نوع تعريف constructed نوع، ويقارنه Typeيمثل الكائن Dictionary<TKey, TValue>فئة.

Imports System
Imports System.Reflection
Imports System.Collections.Generic
Imports System.Security.Permissions

' Define an example interface.
Public Interface ITestArgument
End Interface

' Define an example base class.
Public Class TestBase
End Class

' Define a generic class with one parameter. The parameter
' has three constraints: It must inherit TestBase, it must
' implement ITestArgument, and it must have a parameterless
' constructor.
Public Class Test(Of T As {TestBase, ITestArgument, New})
End Class

' Define a class that meets the constraints on the type
' parameter of class Test.
Public Class TestArgument
    Inherits TestBase
    Implements ITestArgument
    Public Sub New()
    End Sub
End Class

Public Class Example
    ' The following method displays information about a generic
    ' type.
    Private Shared Sub DisplayGenericType(ByVal t As Type)
        Console.WriteLine(vbCrLf & t.ToString())
        Console.WriteLine("   Is this a generic type? " _ 
            & t.IsGenericType)
        Console.WriteLine("   Is this a generic type definition? " _ 
            & t.IsGenericTypeDefinition)

        ' Get the generic type parameters or type arguments.
        Dim typeParameters() As Type = t.GetGenericArguments()

        Console.WriteLine("   List {0} type arguments:", _
            typeParameters.Length)
        For Each tParam As Type In typeParameters
            If tParam.IsGenericParameter Then
                DisplayGenericParameter(tParam)
            Else
                Console.WriteLine("      Type argument: {0}", _
                    tParam)
            End If
        Next
    End Sub

    ' The following method displays information about a generic
    ' type parameter. Generic type parameters are represented by
    ' instances of System.Type, just like ordinary types.
    Private Shared Sub DisplayGenericParameter(ByVal tp As Type)
        Console.WriteLine("      Type parameter: {0} position {1}", _
            tp.Name, tp.GenericParameterPosition)

        Dim classConstraint As Type = Nothing

        For Each iConstraint As Type In tp.GetGenericParameterConstraints()
            If iConstraint.IsInterface Then
                Console.WriteLine("         Interface constraint: {0}", _
                    iConstraint)
            End If
        Next

        If classConstraint IsNot Nothing Then
            Console.WriteLine("         Base type constraint: {0}", _
                tp.BaseType)
        Else
            Console.WriteLine("         Base type constraint: None")
        End If

        Dim sConstraints As GenericParameterAttributes = _
            tp.GenericParameterAttributes And _
            GenericParameterAttributes.SpecialConstraintMask
        If sConstraints = GenericParameterAttributes.None Then
            Console.WriteLine("         No special constraints.")
        Else
            If GenericParameterAttributes.None <> (sConstraints And _
                GenericParameterAttributes.DefaultConstructorConstraint) Then
                Console.WriteLine("         Must have a parameterless constructor.")
            End If
            If GenericParameterAttributes.None <> (sConstraints And _
                GenericParameterAttributes.ReferenceTypeConstraint) Then
                Console.WriteLine("         Must be a reference type.")
            End If
            If GenericParameterAttributes.None <> (sConstraints And _
                GenericParameterAttributes.NotNullableValueTypeConstraint) Then
                Console.WriteLine("         Must be a non-nullable value type.")
            End If
        End If
    End Sub

    <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
    Public Shared Sub Main()
        ' Two ways to get a Type object that represents the generic
        ' type definition of the Dictionary class. 
        '
        ' Use the GetType operator to create the generic type 
        ' definition directly. To specify the generic type definition,
        ' omit the type arguments but retain the comma that separates
        ' them.
        Dim d1 As Type = GetType(Dictionary(Of ,))

        ' You can also obtain the generic type definition from a
        ' constructed class. In this case, the constructed class
        ' is a dictionary of Example objects, with String keys.
        Dim d2 As New Dictionary(Of String, Example)
        ' Get a Type object that represents the constructed type,
        ' and from that get the generic type definition. The 
        ' variables d1 and d4 contain the same type.
        Dim d3 As Type = d2.GetType()
        Dim d4 As Type = d3.GetGenericTypeDefinition()

        ' Display information for the generic type definition, and
        ' for the constructed type Dictionary(Of String, Example).
        DisplayGenericType(d1)
        DisplayGenericType(d2.GetType())

        ' Construct an array of type arguments to substitute for 
        ' the type parameters of the generic Dictionary class.
        ' The array must contain the correct number of types, in 
        ' the same order that they appear in the type parameter 
        ' list of Dictionary. The key (first type parameter)
        ' is of type string, and the type to be contained in the
        ' dictionary is Example.
        Dim typeArgs() As Type = _
            { GetType(String), GetType(Example) }

        ' Construct the type Dictionary(Of String, Example).
        Dim constructed As Type = _
            d1.MakeGenericType(typeArgs)

        DisplayGenericType(constructed)

        Dim o As Object = Activator.CreateInstance(constructed)

        Console.WriteLine(vbCrLf & _
            "Compare types obtained by different methods:")
        Console.WriteLine("   Are the constructed types equal? " _
            & (d2.GetType() Is constructed))
        Console.WriteLine("   Are the generic definitions equal? " _ 
            & (d1 Is constructed.GetGenericTypeDefinition()))

        ' Demonstrate the DisplayGenericType and 
        ' DisplayGenericParameter methods with the Test class 
        ' defined above. This shows base, interface, and special
        ' constraints.
        DisplayGenericType(GetType(Test(Of )))
    End Sub
End Class
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Security.Permissions;

// Define an example interface.
public interface ITestArgument {}

// Define an example base class.
public class TestBase {}

// Define a generic class with one parameter. The parameter
// has three constraints: It must inherit TestBase, it must
// implement ITestArgument, and it must have a parameterless
// constructor.
public class Test<T> where T : TestBase, ITestArgument, new() {}

// Define a class that meets the constraints on the type
// parameter of class Test.
public class TestArgument : TestBase, ITestArgument
{
    public TestArgument() {}
}

public class Example
{
    // The following method displays information about a generic
    // type.
    private static void DisplayGenericType(Type t)
    {
        Console.WriteLine("\r\n {0}", t);
        Console.WriteLine("   Is this a generic type? {0}",
            t.IsGenericType);
        Console.WriteLine("   Is this a generic type definition? {0}",
            t.IsGenericTypeDefinition);

        // Get the generic type parameters or type arguments.
        Type[] typeParameters = t.GetGenericArguments();

        Console.WriteLine("   List {0} type arguments:", 
            typeParameters.Length);
        foreach( Type tParam in typeParameters )
        {
            if (tParam.IsGenericParameter)
            {
                DisplayGenericParameter(tParam);
            }
            else
            {
                Console.WriteLine("      Type argument: {0}",
                    tParam);
            }
        }
    }

    // The following method displays information about a generic
    // type parameter. Generic type parameters are represented by
    // instances of System.Type, just like ordinary types.
    private static void DisplayGenericParameter(Type tp)
    {
        Console.WriteLine("      Type parameter: {0} position {1}", 
            tp.Name, tp.GenericParameterPosition);

        Type classConstraint = null;

        foreach(Type iConstraint in tp.GetGenericParameterConstraints())
        {
            if (iConstraint.IsInterface)
            {
                Console.WriteLine("         Interface constraint: {0}",
                    iConstraint);
            }
        }

        if (classConstraint != null)
        {
            Console.WriteLine("         Base type constraint: {0}", 
                tp.BaseType);
        }
        else
            Console.WriteLine("         Base type constraint: None"); 

        GenericParameterAttributes sConstraints = 
            tp.GenericParameterAttributes & 
            GenericParameterAttributes.SpecialConstraintMask;

        if (sConstraints == GenericParameterAttributes.None)
        {
            Console.WriteLine("         No special constraints.");
        }
        else
        {
            if (GenericParameterAttributes.None != (sConstraints &
                GenericParameterAttributes.DefaultConstructorConstraint))
            {
                Console.WriteLine("         Must have a parameterless constructor.");
            }
            if (GenericParameterAttributes.None != (sConstraints &
                GenericParameterAttributes.ReferenceTypeConstraint))
            {
                Console.WriteLine("         Must be a reference type.");
            }
            if (GenericParameterAttributes.None != (sConstraints &
                GenericParameterAttributes.NotNullableValueTypeConstraint))
            {
                Console.WriteLine("         Must be a non-nullable value type.");
            }
        }
    }

    [PermissionSetAttribute(SecurityAction.Demand, Name="FullTrust")]
    public static void Main()
    {
        // Two ways to get a Type object that represents the generic
        // type definition of the Dictionary class. 
        //
        // Use the typeof operator to create the generic type 
        // definition directly. To specify the generic type definition,
        // omit the type arguments but retain the comma that separates
        // them.
        Type d1 = typeof(Dictionary<,>);

        // You can also obtain the generic type definition from a
        // constructed class. In this case, the constructed class
        // is a dictionary of Example objects, with String keys.
        Dictionary<string, Example> d2 = new Dictionary<string, Example>();
        // Get a Type object that represents the constructed type,
        // and from that get the generic type definition. The 
        // variables d1 and d4 contain the same type.
        Type d3 = d2.GetType();
        Type d4 = d3.GetGenericTypeDefinition();

        // Display information for the generic type definition, and
        // for the constructed type Dictionary<String, Example>.
        DisplayGenericType(d1);
        DisplayGenericType(d2.GetType());

        // Construct an array of type arguments to substitute for 
        // the type parameters of the generic Dictionary class.
        // The array must contain the correct number of types, in 
        // the same order that they appear in the type parameter 
        // list of Dictionary. The key (first type parameter)
        // is of type string, and the type to be contained in the
        // dictionary is Example.
        Type[] typeArgs = {typeof(string), typeof(Example)};

        // Construct the type Dictionary<String, Example>.
        Type constructed = d1.MakeGenericType(typeArgs);

        DisplayGenericType(constructed);

        object o = Activator.CreateInstance(constructed);

        Console.WriteLine("\r\nCompare types obtained by different methods:");
        Console.WriteLine("   Are the constructed types equal? {0}",
            (d2.GetType()==constructed));
        Console.WriteLine("   Are the generic definitions equal? {0}",
            (d1==constructed.GetGenericTypeDefinition()));

        // Demonstrate the DisplayGenericType and 
        // DisplayGenericParameter methods with the Test class 
        // defined above. This shows base, interface, and special
        // constraints.
        DisplayGenericType(typeof(Test<>));
    }
}

التحويل البرمجي للتعليمات البرمجية

  • The تعليمات برمجية يحتوي على the C# using statements (Imports في Visual أساسى) necessary for compilation.

  • لا توجد مراجع تجميع إضافى مطلوبة.

  • يحول برمجياً the تعليمات برمجية at the الأمر خط using csc.exe, vbc.exe, أو cl.exe. إلى يحول برمجياً the تعليمات برمجية في ‏‫Visual Studio, place it في a تطبيق وحدة تحكم قالب مشروع.

راجع أيضًا:

المرجع

Type

MethodInfo

المبادئ

أنواع و عام انعكاس

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

موارد أخرى

generics في .NET Framework