Type.GetGenericParameterConstraints 方法

定义

返回表示当前泛型类型参数约束的 Type 对象的数组。

C#
public virtual Type[] GetGenericParameterConstraints ();

返回

Type[]

表示当前泛型类型参数上的约束的 Type 对象的数组。

例外

当前 Type 对象不是泛型类型参数。 也就是说,IsGenericParameter 属性将返回 false

示例

下面的代码示例定义了一个泛型类型, Test 该泛型类型具有两个具有不同的约束的类型参数。 程序执行时,使用 属性和 方法 GenericParameterAttributes 检查 GetGenericParameterConstraints 约束。

C#
using System;
using System.Reflection;

// Define a sample interface to use as an interface constraint.
public interface ITest {}

// Define a base type to use as a base class constraint.
public class Base {}

// Define the generic type to examine. The first generic type parameter,
// T, derives from the class Base and implements ITest. This demonstrates
// a base class constraint and an interface constraint. The second generic 
// type parameter, U, must be a reference type (class) and must have a 
// default constructor (new()). This demonstrates special constraints.
//
public class Test<T,U> 
    where T : Base, ITest 
    where U : class, new() {}

// Define a type that derives from Base and implements ITest. This type
// satisfies the constraints on T in class Test.
public class Derived : Base, ITest {}

public class Example
{
    public static void Main()
    {
        // To get the generic type definition, omit the type
        // arguments but retain the comma to indicate the number
        // of type arguments. 
        //
        Type def = typeof(Test<,>);
        Console.WriteLine("\r\nExamining generic type {0}", def);

        // Get the type parameters of the generic type definition,
        // and display them.
        //
        Type[] defparams = def.GetGenericArguments();
        foreach (Type tp in defparams)
        {
            Console.WriteLine("\r\nType parameter: {0}", tp.Name);
            Console.WriteLine("\t{0}", 
                ListGenericParameterAttributes(tp));

            // List the base class and interface constraints. The
            // constraints are returned in no particular order. If 
            // there are no class or interface constraints, an empty
            // array is returned.
            //
            Type[] tpConstraints = tp.GetGenericParameterConstraints();
            foreach (Type tpc in tpConstraints)
            {
                Console.WriteLine("\t{0}", tpc);
            }
        }
    }

    // List the variance and special constraint flags. 
    //
    private static string ListGenericParameterAttributes(Type t)
    {
        string retval;
        GenericParameterAttributes gpa = t.GenericParameterAttributes;
        GenericParameterAttributes variance = gpa & 
            GenericParameterAttributes.VarianceMask;

        // Select the variance flags.
        if (variance == GenericParameterAttributes.None)
        {
            retval = "No variance flag;";
        }
        else
        {
            if ((variance & GenericParameterAttributes.Covariant) != 0)
                retval = "Covariant;";
            else
                retval = "Contravariant;";
        }

        // Select 
        GenericParameterAttributes constraints = gpa & 
            GenericParameterAttributes.SpecialConstraintMask;

        if (constraints == GenericParameterAttributes.None)
        {
            retval += " No special constraints";
        }
        else
        {
            if ((constraints & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
                retval += " ReferenceTypeConstraint";
            if ((constraints & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
                retval += " NotNullableValueTypeConstraint";
            if ((constraints & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
                retval += " DefaultConstructorConstraint";
        }

        return retval;
    }
}
/* This example produces the following output:

Examining generic type Test`2[T,U]

Type parameter: T
        No variance flag; no special constraints.
        Base
        ITest

Type parameter: U
        No variance flag; ReferenceTypeConstraint DefaultConstructorConstraint
 */

注解

泛型类型参数上的每个约束都表示为 Type 对象。 使用 IsClass 属性确定约束是否是基类约束;如果属性返回 false ,则约束是接口约束。 如果类型参数没有类约束和接口约束,则返回空数组。

有关泛型反射中使用的术语的固定条件列表,请参阅 IsGenericType 属性注解。

适用于

产品 版本
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard 2.0, 2.1

另请参阅