本文主要讲解“C#类型参数约束的应用方法有哪些”,感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习“C#类型参数约束的应用方法有哪些”!
使用C#类型参数约束的原因:如果要检查泛型列表中的某个项以确定它是否有效或将其与其他项进行比较,编译器必须在一定程度上保证它需要调用的运算符或方法将受到客户端代码可能指定的任何类型参数的支持。这种保证是通过对泛型类定义应用一个或多个约束来实现的。例如,基类约束告诉编译器,只有这种类型的对象或从这种类型派生的对象才能用作类型参数。一旦编译器得到这种保证,它就可以允许在泛型类中调用这种类型的方法。使用上下文关键字应用约束,其中。下面的代码示例演示了通过应用基类约束可以添加到泛型列表类中的功能。
定义泛型类时,可以在实例化类时对客户端代码可用于类型参数的类型施加限制。如果客户端代码试图实例化具有约束不允许的类型的类,它将生成编译时错误。这些限制被称为约束。使用where上下文关键字指定约束。下面列出了六种类型的约束:
T:结构
类型参数必须是值类型。除了Nullable之外,您可以指定任何值类型。
T:类
类型参数必须是引用类型,包括任何类、接口、委托或数组类型。
T:新()
类型参数必须有不带参数的公共构造函数。与其他约束一起使用时,必须指定new()约束。
T:基类名称
类型参数必须是指定的基类或从指定的基类派生。
T:接口名称
参数必须是指定的接口或实现指定的接口。您可以指定多个接口约束。约束接口也可以是通用的。
T:U
为t提供的类型参数必须是为u提供的参数或从为u提供的参数派生的参数。这称为裸类型约束。
C# 类型参数约束代码
public classemploye { privatestringname;privateintidpublicEmployee(字符串,inti){ name=s;id=I;} public string name { get { return name;}设置{ name=value} } publicintID { get { returnid}设置{ id=value} } } public classgenericlistvorywhere t : employee { private classnode { nb
sp; 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 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.Name 属性,因为类型为 T 的所有项都保证是 Employee 对象或从 Employee 继承的对象。
可以对同一类型参数应用多个约束,并且约束自身可以是泛型类型,如下所示:
C# 类型参数约束代码
class EmployeeList where T : Employee, IEmployee, System.IComparable, new() { // ... }
通过约束类型参数,可以增加约束类型及其继承层次结构中的所有类型所支持的允许操作和方法调用的数量。因此,在设计泛型类或方法时,如果要对泛型成员执行除简单赋值之外的任何操作或调用 System.Object 不支持的任何方法,您将需要对该类型参数应用约束。
在应用 where T : class 约束时,建议不要对类型参数使用 == 和 != 运算符,因为这些运算符仅测试引用同一性而不测试值相等性。即使在用作参数的类型中重载这些运算符也是如此。下面的代码说明了这一点;即使 String 类重载 == 运算符,输出也为 false。
C# 类型参数约束代码
public static void OpTest(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); }
这种情况的原因在于,编译器在编译时仅知道 T 是引用类型,因此必须使用对所有引用类型都有效的默认运算符。如果需要测试值相等性,建议的方法是同时应用 where T : IComparable约束,并在将用于构造泛型类的任何类中实现该接口。
C# 未绑定的类型参数
没有约束的类型参数(如公共类 SampleClass{} 中的 T)称为未绑定的类型参数。未绑定的类型参数具有以下规则:
不能使用 != 和 == 运算符,因为无法保证具体类型参数能支持这些运算符。
可以在它们与 System.Object 之间来回转换,或将它们显式转换为任何接口类型。
可以将它们与 null 进行比较。将未绑定的参数与 null 进行比较时,如果类型参数为值类型,则该比较将始终返回 false。
C# 裸类型约束
用作约束的泛型类型参数称为裸类型约束。当具有自己的类型参数的成员函数需要将该参数约束为包含类型的类型参数时,裸类型约束很有用,如下面的示例所示:
C# 类型参数约束代码
class List { void Add(List items) where U : T {/*...*/} }
在上面的示例中,T 在 Add 方法的上下文中是一个裸类型约束,而在 List 类的上下文中是一个未绑定的类型参数。
裸类型约束还可以在泛型类定义中使用。注意,还必须已经和其他任何类型参数一起在尖括号中声明了裸类型约束:
C# 类型参数约束代码
//naked type constraint public class SampleClass where T : V { }
泛型类的裸类型约束的作用非常有限,因为编译器除了假设某个裸类型约束派生自 System.Object 以外,不会做其他任何假设。在希望强制两个类型参数之间的继承关系的情况下,可对泛型类使用裸类型约束。
到此,相信大家对“C#类型参数约束的应用方法有哪些”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/130829.html