C # constraints on generic parameters (C # programming guide)

Source: Internet
Author: User

When defining generic classes, you can impose restrictions on the types of types that client code can use for type parameters when instantiating classes. If the client code attempts to instantiate a class using a type not allowed by a certain constraint, a compile-time error will occur. These restrictions are called constraints. The constraint is to useWhereSpecified by the context keyword. The following table lists the six types of constraints:

Constraints Description

T: Structure

The type parameter must be a value type. You can specify any value type except nullable. For more information, see use a void type (C # programming guide ).

T: Class

The type parameter must be a reference type, including any class, interface, delegate, or array type.

T: New ()

The type parameter must have a public constructor without parameters. When used together with other constraints,New ()The constraint must be specified at the end.

T: <Base Class Name>

The type parameter must be a specified base class or derived from the specified base class.

T: <Interface Name>

The type parameter must be a specified interface or implement the specified interface. Multiple interface constraints can be specified. The constraint interface can also be generic.

T: u

The type parameter provided for T must be provided for U or derived from U. This is called the bare type constraint.

Reasons for restrictions

If you want to check an item in the generic list to determine whether it is valid, or compare it with another item, the compiler must ensure that the operators or methods to be called by the compiler are supported by any type of parameters that may be specified by the client code. This guarantee is obtained by applying one or more constraints to the generic class definition. For example, a base class constraint tells the compiler that only objects of this type or objects derived from this type can be used as type parameters. Once the compiler has this guarantee, it can allow calling methods of this type in generic classes. Constraint is the use of context keywordsWhereApplication. The following code example shows how to add a base class constraintGenericlist <t>Class (in the generic introduction (C # programming guide.

C # 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)
{
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)
{
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 = 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;
}
}

Constraints enable generic classes to useEmployee. NameAttribute, because all the items whose type is t are guaranteed to beEmployeeObject or slaveEmployeeThe inherited object.

You can apply multiple constraints to parameters of the same type, and the constraints themselves can be generic types, as shown below:

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

The constraint type parameter can be used to increase the number of allowed operations and method calls supported by the constraint type and all types in its inheritance hierarchy. Therefore, when designing a generic class or method, if you want to perform any operation or call other than simple assignment to a generic memberSystem. ObjectAny method not supported, you will need to apply constraints on this type of parameter.

In the ApplicationWhere T: ClassWe do not recommend that you use type parameters=And! =Operator, because these operators only test the reference identity, and do not test the value equality. This is true even if these operators are reloaded in the type used as a parameter. The following code illustrates this, even if the string class is overloaded=The output value is also false.

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

The reason for this is that the compiler only knows at compilation that T is a reference type, so the default operator that is valid for all reference types must be used. If you need to test the value equality, we recommend that you use the same method at the same time.Where T: icomparable <t>And implement this interface in any class used to construct a generic class.

Unbound type parameter

Type parameters without constraints (such as public classes)Sampleclass <t> {}T) is called an unbound type parameter. Unbound type parameters have the following rules:

  • Unavailable! =And=It is not guaranteed that a specific type parameter supports these operators.

  • You canSystem. ObjectOr explicitly convert them to any interface type.

  • You can compare them with null. Associate unbound parametersNullIf the type parameter is a value type, the comparison always returns false.

Bare type constraints

The generic type parameters used as constraints are called Bare type constraints. When a member function with its own type parameters needs to constrain this parameter to include type parameters, the bare type constraints are useful, as shown in the following example:

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

In the preceding example,TInAddThe method context is a bare type constraint, whileListClass is an unbound type parameter in the context.

Bare type constraints can also be used in generic class definitions. Note that the bare type constraint must be declared in angle brackets with any other type parameter:

C # copy code
//naked type constraintpublic class SampleClass<T, U, V> where T : V { }

The bare type constraints of generic classes have very limited functions, because the compiler assumes that a bare type constraint is derived fromSystem. ObjectNo other assumptions. When you want to force the inheritance relationship between two type parameters, you can use the bare type constraint for the generic class.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.