Type.ContainsGenericParameters 属性
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
获取一个值,该值指示当前 Type 对象是否具有尚未被特定类型替代的类型参数。
public:
virtual property bool ContainsGenericParameters { bool get(); };
public virtual bool ContainsGenericParameters { get; }
member this.ContainsGenericParameters : bool
Public Overridable ReadOnly Property ContainsGenericParameters As Boolean
属性值
如果 true
对象本身是泛型类型形参或者具有尚未提供特定类型的类型形参,则为 Type;否则为 false
。
示例
下面的示例定义了一个具有两个类型参数的泛型类,然后定义了第一个派生自第一个类的泛型类。 派生类的基类具有两个类型参数:第一个是 Int32 ,第二个是派生类型的类型参数。 该示例显示有关这些泛型类的信息,包括属性报告的位置 GenericParameterPosition 。
using namespace System;
using namespace System::Reflection;
using namespace System::Collections::Generic;
// Define a base class with two type parameters.
generic< class T,class U >
public ref class Base {};
// Define a derived class. The derived class inherits from a constructed
// class that meets the following criteria:
// (1) Its generic type definition is Base<T, U>.
// (2) It specifies int for the first type parameter.
// (3) For the second type parameter, it uses the same type that is used
// for the type parameter of the derived class.
// Thus, the derived class is a generic type with one type parameter, but
// its base class is an open constructed type with one type argument and
// one type parameter.
generic<class V>
public ref class Derived : Base<int,V> {};
public ref class Test
{
public:
static void Main()
{
Console::WriteLine(
L"\r\n--- Display a generic type and the open constructed");
Console::WriteLine(L" type from which it is derived.");
// Create a Type object representing the generic type definition
// for the Derived type. Note the absence of type arguments.
//
Type^ derivedType = Derived::typeid;
DisplayGenericTypeInfo(derivedType);
// Display its open constructed base type.
DisplayGenericTypeInfo(derivedType->BaseType);
}
private:
static void DisplayGenericTypeInfo(Type^ t)
{
Console::WriteLine(L"\r\n{0}", t);
Console::WriteLine(L"\tIs this a generic type definition? {0}",
t->IsGenericTypeDefinition);
Console::WriteLine(L"\tIs it a generic type? {0}", t->IsGenericType);
Console::WriteLine(L"\tDoes it have unassigned generic parameters? {0}",
t->ContainsGenericParameters);
if (t->IsGenericType)
{
// If this is a generic type, display the type arguments.
//
array<Type^>^typeArguments = t->GetGenericArguments();
Console::WriteLine(L"\tList type arguments ({0}):",
typeArguments->Length);
System::Collections::IEnumerator^ myEnum =
typeArguments->GetEnumerator();
while (myEnum->MoveNext())
{
Type^ tParam = safe_cast<Type^>(myEnum->Current);
// IsGenericParameter is true only for generic type
// parameters.
//
if (tParam->IsGenericParameter)
{
Console::WriteLine(
L"\t\t{0} (unassigned - parameter position {1})",
tParam, tParam->GenericParameterPosition);
}
else
{
Console::WriteLine(L"\t\t{0}", tParam);
}
}
}
}
};
int main()
{
Test::Main();
}
/* This example produces the following output:
--- Display a generic type and the open constructed
type from which it is derived.
Derived`1[V]
Is this a generic type definition? True
Is it a generic type? True
Does it have unassigned generic parameters? True
List type arguments (1):
V (unassigned - parameter position 0)
Base`2[System.Int32,V]
Is this a generic type definition? False
Is it a generic type? True
Does it have unassigned generic parameters? True
List type arguments (2):
System.Int32
V (unassigned - parameter position 0)
*/
using System;
using System.Reflection;
using System.Collections.Generic;
// Define a base class with two type parameters.
public class Base<T, U> { }
// Define a derived class. The derived class inherits from a constructed
// class that meets the following criteria:
// (1) Its generic type definition is Base<T, U>.
// (2) It specifies int for the first type parameter.
// (3) For the second type parameter, it uses the same type that is used
// for the type parameter of the derived class.
// Thus, the derived class is a generic type with one type parameter, but
// its base class is an open constructed type with one type argument and
// one type parameter.
public class Derived<V> : Base<int, V> { }
public class Test
{
public static void Main()
{
Console.WriteLine(
"\r\n--- Display a generic type and the open constructed");
Console.WriteLine(" type from which it is derived.");
// Create a Type object representing the generic type definition
// for the Derived type, by omitting the type argument. (For
// types with multiple type parameters, supply the commas but
// omit the type arguments.)
//
Type derivedType = typeof(Derived<>);
DisplayGenericTypeInfo(derivedType);
// Display its open constructed base type.
DisplayGenericTypeInfo(derivedType.BaseType);
}
private static void DisplayGenericTypeInfo(Type t)
{
Console.WriteLine("\r\n{0}", t);
Console.WriteLine("\tIs this a generic type definition? {0}",
t.IsGenericTypeDefinition);
Console.WriteLine("\tIs it a generic type? {0}",
t.IsGenericType);
Console.WriteLine("\tDoes it have unassigned generic parameters? {0}",
t.ContainsGenericParameters);
if (t.IsGenericType)
{
// If this is a generic type, display the type arguments.
//
Type[] typeArguments = t.GetGenericArguments();
Console.WriteLine("\tList type arguments ({0}):",
typeArguments.Length);
foreach (Type tParam in typeArguments)
{
// IsGenericParameter is true only for generic type
// parameters.
//
if (tParam.IsGenericParameter)
{
Console.WriteLine(
"\t\t{0} (unassigned - parameter position {1})",
tParam,
tParam.GenericParameterPosition);
}
else
{
Console.WriteLine("\t\t{0}", tParam);
}
}
}
}
}
/* This example produces the following output:
--- Display a generic type and the open constructed
type from which it is derived.
Derived`1[V]
Is this a generic type definition? True
Is it a generic type? True
Does it have unassigned generic parameters? True
List type arguments (1):
V (unassigned - parameter position 0)
Base`2[System.Int32,V]
Is this a generic type definition? False
Is it a generic type? True
Does it have unassigned generic parameters? True
List type arguments (2):
System.Int32
V (unassigned - parameter position 0)
*/
Imports System.Reflection
Imports System.Collections.Generic
' Define a base class with two type parameters.
Public Class Base(Of T, U)
End Class
' Define a derived class. The derived class inherits from a constructed
' class that meets the following criteria:
' (1) Its generic type definition is Base<T, U>.
' (2) It uses int for the first type parameter.
' (3) For the second type parameter, it uses the same type that is used
' for the type parameter of the derived class.
' Thus, the derived class is a generic type with one type parameter, but
' its base class is an open constructed type with one assigned type
' parameter and one unassigned type parameter.
Public Class Derived(Of V)
Inherits Base(Of Integer, V)
End Class
Public Class Test
Public Shared Sub Main()
Console.WriteLine(vbCrLf _
& "--- Display a generic type and the open constructed")
Console.WriteLine(" type from which it is derived.")
' Create a Type object representing the generic type definition
' for the Derived type, by omitting the type argument. (For
' types with multiple type parameters, supply the commas but
' omit the type arguments.)
'
Dim derivedType As Type = GetType(Derived(Of ))
DisplayGenericTypeInfo(derivedType)
' Display its open constructed base type.
DisplayGenericTypeInfo(derivedType.BaseType)
End Sub
Private Shared Sub DisplayGenericTypeInfo(ByVal t As Type)
Console.WriteLine(vbCrLf & "{0}", t)
Console.WriteLine(vbTab & "Is this a generic type definition? " _
& t.IsGenericTypeDefinition)
Console.WriteLine(vbTab & "Is it a generic type? " _
& t.IsGenericType)
Console.WriteLine(vbTab _
& "Does it have unassigned generic parameters? " _
& t.ContainsGenericParameters)
If t.IsGenericType Then
' If this is a generic type, display the type arguments.
'
Dim typeArguments As Type() = t.GetGenericArguments()
Console.WriteLine(vbTab & "List type arguments (" _
& typeArguments.Length & "):")
For Each tParam As Type In typeArguments
' IsGenericParameter is true only for generic type
' parameters.
'
If tParam.IsGenericParameter Then
Console.WriteLine(vbTab & vbTab & tParam.ToString() _
& " (unassigned - parameter position " _
& tParam.GenericParameterPosition & ")")
Else
Console.WriteLine(vbTab & vbTab & tParam.ToString())
End If
Next tParam
End If
End Sub
End Class
' This example produces the following output:
'
'--- Display a generic type and the open constructed
' type from which it is derived.
'
'Derived`1[V]
' Is this a generic type definition? True
' Is it a generic type? True
' Does it have unassigned generic parameters? True
' List type arguments (1):
' V (unassigned - parameter position 0)
'
'Base`2[System.Int32,V]
' Is this a generic type definition? False
' Is it a generic type? True
' Does it have unassigned generic parameters? True
' List type parameters (2):
' System.Int32
' V (unassigned - parameter position 0)
'
注解
若要创建类型的实例,在类型本身的类型参数、任何封闭泛型类型或任何类型的元素中都不能有泛型类型定义或开放式构造类型。 另一种说法是,在递归检查时,类型不能包含泛型类型参数。
由于类型可能会很复杂,因此做出此决定非常困难。 为方便起见,若要减少出现错误的可能性, ContainsGenericParameters 属性提供了一种标准方法来区分封闭式构造类型(可以实例化和开放构造的类型,这是不可能的)。 如果 ContainsGenericParameters 属性返回 true
,则无法实例化该类型。
ContainsGenericParameters属性以递归方式搜索类型参数。 例如,它 true
为元素类型为的数组返回 A<T>
(A(Of T)
Visual Basic) 中,即使数组本身不是泛型。 将此与 IsGenericType 为数组返回的属性的行为进行比较 false
。
有关示例类和显示属性值的表 ContainsGenericParameters ,请参阅 IsGenericType 。