Поделиться через


Type.IsGenericType Свойство

Определение

Возвращает значение, указывающее, является ли текущий тип универсальным.

public:
 virtual property bool IsGenericType { bool get(); };
public virtual bool IsGenericType { get; }
member this.IsGenericType : bool
Public Overridable ReadOnly Property IsGenericType As Boolean

Значение свойства

true Значение , если текущий тип является универсальным; в противном случае — false.

Примеры

В следующем примере кода отображается значение IsGenericTypeсвойств , IsGenericTypeDefinition, IsGenericParameterи ContainsGenericParameters для типов, описанных в разделе Примечания. Объяснения значений свойств см. в сопроводительной таблице статьи Примечания.

using namespace System;
using namespace System::Reflection;

generic<typename T, typename U> public ref class Base {};

generic<typename T> public ref class G {};

generic<typename V> public ref class Derived : Base<String^, V>
{
public: 
    G<Derived<V>^>^ F;

    ref class Nested {};
};

void DisplayGenericType(Type^ t, String^ caption)
{
    Console::WriteLine("\n{0}", caption);
    Console::WriteLine("    Type: {0}", t);

    Console::WriteLine("\t            IsGenericType: {0}", 
        t->IsGenericType);
    Console::WriteLine("\t  IsGenericTypeDefinition: {0}", 
        t->IsGenericTypeDefinition);
    Console::WriteLine("\tContainsGenericParameters: {0}", 
        t->ContainsGenericParameters);
    Console::WriteLine("\t       IsGenericParameter: {0}", 
        t->IsGenericParameter);
}

void main()
{
    // Get the generic type definition for Derived, and the base
    // type for Derived.
    //
    Type^ tDerived = Derived::typeid;
    Type^ tDerivedBase = tDerived->BaseType;

    // Declare an array of Derived<int>, and get its type.
    //
    array<Derived<int>^>^ d = gcnew array<Derived<int>^>(0);
    Type^ tDerivedArray = d->GetType();

    // Get a generic type parameter, the type of a field, and a
    // type that is nested in Derived. Notice that in order to
    // get the nested type it is necessary to either (1) specify
    // the generic type definition Derived::typeid, as shown here,
    // or (2) specify a type parameter for Derived.
    //
    Type^ tT = Base::typeid->GetGenericArguments()[0];
    Type^ tF = tDerived->GetField("F")->FieldType;
    Type^ tNested = Derived::Nested::typeid;

    DisplayGenericType(tDerived, "generic<V> Derived");
    DisplayGenericType(tDerivedBase, "Base type of generic<V> Derived");
    DisplayGenericType(tDerivedArray, "Array of Derived<int>");
    DisplayGenericType(tT, "Type parameter T from generic<T> Base");
    DisplayGenericType(tF, "Field type, G<Derived<V>^>^");
    DisplayGenericType(tNested, "Nested type in generic<V> Derived");
}

/* This code example produces the following output:

generic<V> Derived
    Type: Derived`1[V]
                    IsGenericType: True
          IsGenericTypeDefinition: True
        ContainsGenericParameters: True
               IsGenericParameter: False

Base type of generic<V> Derived
    Type: Base`2[System.String,V]
                    IsGenericType: True
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: False

Array of Derived<int>
    Type: Derived`1[System.Int32][]
                    IsGenericType: False
          IsGenericTypeDefinition: False
        ContainsGenericParameters: False
               IsGenericParameter: False

Type parameter T from generic<T> Base
    Type: T
                    IsGenericType: False
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: True

Field type, G<Derived<V>^>^
    Type: G`1[Derived`1[V]]
                    IsGenericType: True
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: False

Nested type in generic<V> Derived
    Type: Derived`1+Nested[V]
                    IsGenericType: True
          IsGenericTypeDefinition: True
        ContainsGenericParameters: True
               IsGenericParameter: False
 */
using System;
using System.Reflection;

public class Base<T, U> {}

public class Derived<V> : Base<string, V>
{
    public G<Derived <V>> F;

    public class Nested {}
}

public class G<T> {}

class Example
{
    public static void Main()
    {
        // Get the generic type definition for Derived, and the base
        // type for Derived.
        //
        Type tDerived = typeof(Derived<>);
        Type tDerivedBase = tDerived.BaseType;

        // Declare an array of Derived<int>, and get its type.
        //
        Derived<int>[] d = new Derived<int>[0];
        Type tDerivedArray = d.GetType();

        // Get a generic type parameter, the type of a field, and a
        // type that is nested in Derived. Notice that in order to
        // get the nested type it is necessary to either (1) specify
        // the generic type definition Derived<>, as shown here,
        // or (2) specify a type parameter for Derived.
        //
        Type tT = typeof(Base<,>).GetGenericArguments()[0];
        Type tF = tDerived.GetField("F").FieldType;
        Type tNested = typeof(Derived<>.Nested);

        DisplayGenericType(tDerived, "Derived<V>");
        DisplayGenericType(tDerivedBase, "Base type of Derived<V>");
        DisplayGenericType(tDerivedArray, "Array of Derived<int>");
        DisplayGenericType(tT, "Type parameter T from Base<T>");
        DisplayGenericType(tF, "Field type, G<Derived<V>>");
        DisplayGenericType(tNested, "Nested type in Derived<V>");
    }

    public static void DisplayGenericType(Type t, string caption)
    {
        Console.WriteLine("\n{0}", caption);
        Console.WriteLine("    Type: {0}", t);

        Console.WriteLine("\t            IsGenericType: {0}", 
            t.IsGenericType);
        Console.WriteLine("\t  IsGenericTypeDefinition: {0}", 
            t.IsGenericTypeDefinition);
        Console.WriteLine("\tContainsGenericParameters: {0}", 
            t.ContainsGenericParameters);
        Console.WriteLine("\t       IsGenericParameter: {0}", 
            t.IsGenericParameter);
    }
}

/* This code example produces the following output:

Derived<V>
    Type: Derived`1[V]
                    IsGenericType: True
          IsGenericTypeDefinition: True
        ContainsGenericParameters: True
               IsGenericParameter: False

Base type of Derived<V>
    Type: Base`2[System.String,V]
                    IsGenericType: True
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: False

Array of Derived<int>
    Type: Derived`1[System.Int32][]
                    IsGenericType: False
          IsGenericTypeDefinition: False
        ContainsGenericParameters: False
               IsGenericParameter: False

Type parameter T from Base<T>
    Type: T
                    IsGenericType: False
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: True

Field type, G<Derived<V>>
    Type: G`1[Derived`1[V]]
                    IsGenericType: True
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: False

Nested type in Derived<V>
    Type: Derived`1+Nested[V]
                    IsGenericType: True
          IsGenericTypeDefinition: True
        ContainsGenericParameters: True
               IsGenericParameter: False
 */
open System

type Base<'T, 'U>() = class end

type G<'T>() = class end

type Derived<'V>() =
    inherit Base<string, 'V>()
    
    [<DefaultValue>]
    val mutable public F : G<Derived<'V>>

let displayGenericType (t: Type) caption =
    printfn $"\n{caption}"
    printfn $"    Type: {t}"

    printfn $"\t            IsGenericType: {t.IsGenericType}" 
    printfn $"\t  IsGenericTypeDefinition: {t.IsGenericTypeDefinition}" 
    printfn $"\tContainsGenericParameters: {t.ContainsGenericParameters}"
    printfn $"\t       IsGenericParameter: {t.IsGenericParameter}"

// Get the generic type definition for Derived, and the base
// type for Derived.
let tDerived = typeof<Derived<_>>.GetGenericTypeDefinition()
let tDerivedBase = tDerived.BaseType

// Declare an array of Derived<int>, and get its type.
let d = Array.zeroCreate<Derived<int>> 0
let tDerivedArray = d.GetType()

// Get a generic type parameter, the type of a field, and a
// type that is nested in Derived. Notice that in order to
// get the nested type it is necessary to either (1) specify
// the generic type definition Derived<>, as shown here,
// or (2) specify a type parameter for Derived.
let tT = typeof<Base<_,_>>.GetGenericTypeDefinition().GetGenericArguments()[0]
let tF = tDerived.GetField("F").FieldType

displayGenericType tDerived "Derived<V>"
displayGenericType tDerivedBase "Base type of Derived<V>"
displayGenericType tDerivedArray "Array of Derived<int>"
displayGenericType tT "Type parameter T from Base<T>"
displayGenericType tF "Field type, G<Derived<V>>"

(* This code example produces the following output:

Derived<V>
    Type: Derived`1[V]
                    IsGenericType: True
          IsGenericTypeDefinition: True
        ContainsGenericParameters: True
               IsGenericParameter: False

Base type of Derived<V>
    Type: Base`2[System.String,V]
                    IsGenericType: True
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: False

Array of Derived<int>
    Type: Derived`1[System.Int32][]
                    IsGenericType: False
          IsGenericTypeDefinition: False
        ContainsGenericParameters: False
               IsGenericParameter: False

Type parameter T from Base<T>
    Type: T
                    IsGenericType: False
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: True

Field type, G<Derived<V>>
    Type: G`1[Derived`1[V]]
                    IsGenericType: True
          IsGenericTypeDefinition: False
        ContainsGenericParameters: True
               IsGenericParameter: False
 *)
Imports System.Reflection

' 
Public Class Base(Of T, U)
End Class

Public Class Derived(Of V) 
    Inherits Base(Of String, V)

    Public F As G(Of Derived(Of V))

    Public Class Nested
    End Class
End Class

Public Class G(Of T)
End Class 

Module Example

    Sub Main

        ' Get the generic type definition for Derived, and the base
        ' type for Derived.
        '
        Dim tDerived As Type = GetType(Derived(Of ))
        Dim tDerivedBase As Type = tDerived.BaseType

        ' Declare an array of Derived(Of Integer), and get its type.
        '
        Dim d(0) As Derived(Of Integer)
        Dim tDerivedArray As Type = d.GetType()

        ' Get a generic type parameter, the type of a field, and a
        ' type that is nested in Derived. Notice that in order to
        ' get the nested type it is necessary to either (1) specify
        ' the generic type definition Derived(Of ), as shown here,
        ' or (2) specify a type parameter for Derived.
        '
        Dim tT As Type = GetType(Base(Of ,)).GetGenericArguments()(0)
        Dim tF As Type = tDerived.GetField("F").FieldType
        Dim tNested As Type = GetType(Derived(Of ).Nested)

        DisplayGenericType(tDerived, "Derived(Of V)")
        DisplayGenericType(tDerivedBase, "Base type of Derived(Of V)")
        DisplayGenericType(tDerivedArray, "Array of Derived(Of Integer)")
        DisplayGenericType(tT, "Type parameter T from Base(Of T)")
        DisplayGenericType(tF, "Field type, G(Of Derived(Of V))")
        DisplayGenericType(tNested, "Nested type in Derived(Of V)")

    End Sub

    Sub DisplayGenericType(ByVal t As Type, ByVal caption As String)

        Console.WriteLine(vbLf & caption)
        Console.WriteLine("    Type: {0}", t)

        Console.WriteLine(vbTab & "            IsGenericType: {0}", _
            t.IsGenericType)
        Console.WriteLine(vbTab & "  IsGenericTypeDefinition: {0}", _
            t.IsGenericTypeDefinition)
        Console.WriteLine(vbTab & "ContainsGenericParameters: {0}", _
            t.ContainsGenericParameters)
        Console.WriteLine(vbTab & "       IsGenericParameter: {0}", _
            t.IsGenericParameter)

    End Sub

End Module

' This code example produces the following output:
'
'Derived(Of V)
'    Type: Derived`1[V]
'                    IsGenericType: True
'          IsGenericTypeDefinition: True
'        ContainsGenericParameters: True
'               IsGenericParameter: False
'
'Base type of Derived(Of V)
'    Type: Base`2[System.String,V]
'                    IsGenericType: True
'          IsGenericTypeDefinition: False
'        ContainsGenericParameters: True
'               IsGenericParameter: False
'
'Array of Derived(Of Integer)
'    Type: Derived`1[System.Int32][]
'                    IsGenericType: False
'          IsGenericTypeDefinition: False
'        ContainsGenericParameters: False
'               IsGenericParameter: False
'
'Type parameter T from Base(Of T)
'    Type: T
'                    IsGenericType: False
'          IsGenericTypeDefinition: False
'        ContainsGenericParameters: True
'               IsGenericParameter: True
'
'Field type, G(Of Derived(Of V))
'    Type: G`1[Derived`1[V]]
'                    IsGenericType: True
'          IsGenericTypeDefinition: False
'        ContainsGenericParameters: True
'               IsGenericParameter: False
'
'Nested type in Derived(Of V)
'    Type: Derived`1+Nested[V]
'                    IsGenericType: True
'          IsGenericTypeDefinition: True
'        ContainsGenericParameters: True
'               IsGenericParameter: False

Комментарии

Используйте свойство , IsGenericType чтобы определить, представляет ли Type объект универсальный тип. Используйте свойство , ContainsGenericParameters чтобы определить, представляет ли Type объект открытый или закрытый сконструированный тип.

Примечание

Свойство IsGenericType возвращает значение false , если непосредственный тип не является универсальным. Например, массив, элементы которого имеют тип A<int> (A(Of Integer) в Visual Basic), сам по себе не является универсальным типом.

В следующей таблице перечислены инвариантные условия для распространенных терминов, используемых в универсальном отражении.

Термин Инвариант
определение универсального типа Значение свойства IsGenericTypeDefinitiontrue.

Определяет универсальный тип. Созданный тип создается путем вызова MakeGenericType метода для Type объекта , представляющего определение универсального типа, и указания массива аргументов типа.

MakeGenericType может вызываться только в определениях универсальных типов.

Любое определение универсального типа является универсальным типом ( IsGenericType свойство — true), но обратное не является истинным.
универсальный тип Значение свойства IsGenericTypetrue.

Может быть определением универсального типа, открытым или закрытым сконструированным типом.

Обратите внимание, что тип массива, тип элемента которого является универсальным, сам по себе не является универсальным типом. То же самое относится и к объекту Type , представляющего указатель на универсальный тип.
открытый сконструированный тип Значение свойства ContainsGenericParameterstrue.

Примерами являются универсальный тип с параметрами неназначенного типа, тип, вложенный в определение универсального типа или открытый сконструированный тип, или универсальный тип с аргументом типа, для которого ContainsGenericParameters свойство имеет значение true.

невозможно создать экземпляр открытого сконструированного типа.

Обратите внимание, что не все открытые сконструированные типы являются универсальными. Например, массив, тип элемента которого является определением универсального типа, не является универсальным, а указатель на открытый сконструированный тип не является универсальным.
закрытый сконструированный тип Значение свойства ContainsGenericParametersfalse.

При рекурсивном анализе тип не имеет неназначенных универсальных параметров.
параметр универсального типа Значение свойства IsGenericParametertrue.

Значение свойства ContainsGenericParameterstrue.

В определении универсального типа — заполнитель для типа, который будет назначен позже.
аргумент универсального типа Может иметь любой тип, включая параметр универсального типа.

Аргументы типа указываются в виде массива объектов, передаваемых Type методу MakeGenericType при создании созданного универсального типа. Если необходимо создать экземпляры результирующего типа, ContainsGenericParameters свойство должно быть false для всех аргументов типа.

В следующем примере кода и таблице показаны некоторые из этих терминов и инвариантов. Класс Derived представляет особый интерес, так как его базовый тип является сконструированным типом, который имеет сочетание типов и параметров типов в списке аргументов типов.

generic<typename T, typename U> public ref class Base {};

generic<typename T> public ref class G {};

generic<typename V> public ref class Derived : Base<String^, V>
{
public:
    G<Derived<V>^>^ F;

    ref class Nested {};
};
public class Base<T, U> {}

public class Derived<V> : Base<string, V>
{
    public G<Derived <V>> F;

    public class Nested {}
}

public class G<T> {}
type Base<'T, 'U>() = class end

type G<'T>() = class end

type Derived<'V>() =
    inherit Base<string, 'V>()
    
    [<DefaultValue>]
    val mutable public F : G<Derived<'V>>
Public Class Base(Of T, U)
End Class

Public Class Derived(Of V)
    Inherits Base(Of String, V)

    Public F As G(Of Derived(Of V))

    Public Class Nested
    End Class
End Class

Public Class G(Of T)
End Class

В следующей таблице приведены примеры, которые используют и строят классы Base, Derivedи G. Если код C++ и C# совпадает, отображается только одна запись.

Пример Инварианты
Derived(Of V)

Derived<V>
Для этого типа:

IsGenericType имеет значение true.

IsGenericTypeDefinition имеет значение true.

ContainsGenericParameters имеет значение true.
Base(Of String, V)

Base<String,V>

Base<String^,V>
Для этого типа:

IsGenericType имеет значение true.

IsGenericTypeDefinition имеет значение false.

ContainsGenericParameters имеет значение true.
Dim d() As Derived(Of Integer)

Derived<int>[] d;

array<Derived<int>^>^ d;
Для типа переменной d:

IsGenericType имеет значение потому false , что d является массивом.

IsGenericTypeDefinition имеет значение false.

ContainsGenericParameters имеет значение false.
T, Uи V (везде, где они отображаются) IsGenericParameter имеет значение true.

IsGenericType это false связано с тем, что невозможно ограничить параметр типа универсальными типами.

IsGenericTypeDefinition имеет значение false.

ContainsGenericParameters имеет значение потому true , что T, Uи V сами являются параметрами универсального типа. Это не означает ничего о аргументах типа, которые будут назначены им позже.
Тип поля F IsGenericType имеет значение true.

IsGenericTypeDefinitionимеет значение , false так как тип был назначен параметру типа .G Обратите внимание, что это эквивалентно вызову MakeGenericType метода .

ContainsGenericParameters имеет значение , true так как тип поля F имеет аргумент типа, который является открытым сконструированным типом. Сконструированный тип открыт, так как его аргумент типа (т. е Base. ) является универсальным определением типа. Это иллюстрирует рекурсивную природу IsGenericType свойства .
Вложенный класс Nested IsGenericType имеет значение true, даже если Nested класс не имеет собственных параметров универсального типа, так как он вложен в универсальный тип.

IsGenericTypeDefinition имеет значение true. То есть можно вызвать MakeGenericType метод и указать параметр типа включающего типа , Derived.

ContainsGenericParameters имеет значение , true так как включающий тип Derived, имеет параметры универсального типа. Это иллюстрирует рекурсивную природу ContainsGenericParameters свойства .

Применяется к

См. также раздел