http://msdn.microsoft.com/zh-cn/library/d5x73970.aspx

Constraints on Type Parameters (C# Programming Guide) 

 

The following table lists the six types of constraints:

Constraint

Description

where T: struct

Using Nullable Types (C# Programming Guide) for more information.

where T : class

The type argument must be a reference type; this applies also to any class, interface, delegate, or array type.

where T : new()

new() constraint must be specified last.

where T : <base class name>

The type argument must be or derive from the specified base class.

where T : <interface name>

The constraining interface can also be generic.

where T : U

The type argument supplied for T must be or derive from the argument supplied for U.

Introduction to Generics (C# Programming Guide)) by applying a base class constraint.

 
public class Employee
{
    private string name;
    private int id;

    public Employee(string s, int i)
    {
        name = s;
        id = i;
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int ID
    {
        get { return id; }
        set { id = value; }
    }
}

public class GenericList<T> where T : Employee
{
    private class Node
    {
        private Node next;
        private T data;

        public Node(T t)
        {
            next = null;
            data = t;
        }

        public Node Next
        {
            get { return next; }
            set { next = value; }
        }

        public T Data
        {
            get { return data; }
            set { data = value; }
        }
    }

    private Node head;

    public GenericList() //constructor
    {
        head = null;
    }

    public void AddHead(T t)
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    public IEnumerator<T> GetEnumerator()
    {
        Node current = head;

        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }

    public T FindFirstOccurrence(string s)
    {
        Node current = head;
        T t = null;

        while (current != null)
        {
            //The constraint enables access to the Name property.
            if (current.Data.Name == s)
            {
                t = current.Data;
                break;
            }
            else
            {
                current = current.Next;
            }
        }
        return t;
    }
}


Employee.

Multiple constraints can be applied to the same type parameter, and the constraints themselves can be generic types, as follows:

 
class EmployeeList<T> where T : Employee, IEmployee, System.IComparable<T>, new()
{
    // ...
}


System.Object, you will have to apply constraints to the type parameter.

== operator.

 
public static void OpTest<T>(T s, T t) where T : class
{
    System.Console.WriteLine(s == t);
}
static void Main()
{
    string s1 = "target";
    System.Text.StringBuilder sb = new System.Text.StringBuilder("target");
    string s2 = sb.ToString();
    OpTest<string>(s1, s2);
}


where T : IComparable<T> constraint and implement that interface in any class that will be used to construct the generic class.

You can apply constraints to multiple parameters, and multiple constraints to a single parameter, as shown in the following example:

 
class Base { }
class Test<T, U>
    where U : struct
    where T : Base, new() { }


Unbounded type parameters have the following rules:

  • == operators cannot be used because there is no guarantee that the concrete type argument will support these operators.

  • System.Object or explicitly converted to any interface type.

  • null, the comparison will always return false if the type argument is a value type.

The use of a generic type parameter as a constraint is useful when a member function with its own type parameter has to constrain that parameter to the type parameter of the containing type, as shown in the following example:

class List<T>
{
    void Add<U>(List<U> items) where U : T {/*...*/}
}


List class.

Note that the type parameter must be declared within the angle brackets together with any other type parameters:

//Type parameter V is used as a type constraint.
public class SampleClass<T, U, V> where T : V { }


Use type parameters as constraints on generic classes in scenarios in which you want to enforce an inheritance relationship between two type parameters.

相关文章: