• 类型参数的约束


    若要检查表中的一个元素,以确定它是否合法或是否可以与其他元素相比较,那么编译器必须保证:客户代码中可能出现的所有类型参数,都要支持所需调用的操作或方法。这种保证是通过在泛型类的定义中,应用一个或多个约束而得到的。一个约束类型是一种基类约束,它通知编译器,只有这个类型的对象或从这个类型派生的对象,可被用作类型参数。一旦编译器得到这样的保证,它就允许在泛型类中调用这个类型的方法。上下文关键字where用以实现约束。下面的示例代码说明了应用基类约束,为MyList<T>类增加功能

    public class Employee
    {
     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; }
            }
     
        }
    }
    class MyList<T> where T: Employee
    {
     //Rest of class as before.
      public T FindFirstOccurrence(string s)
      {
       T t = null;
       Reset();
       while (HasItems())
       {
          if (current != null)
          {
    //The constraint enables this:
             if (current.Data.Name == s)
             {
                t = current.Data;
                break;
             }
             else
             {
                current = current.Next;
             }
          } //end if
       } // end while
      return t;
      }
    }

    约束使得泛型类能够使用Employee.Name属性,因为所有为类型T的元素,都是一个Employee对象或是一个继承自Employee的对象。

     

    同一个类型参数可应用多个约束。约束自身也可以是泛型类,如下:

    class MyList<T> where T: Employee, IEmployee,  IComparable<T>,  new()
    {…}

     

        下表列出了五类约束:

    约束

    描述

    where T: struct

    类型参数必须为值类型。

    where T : class

    类型参数必须为引用类型。

    where T : new()

    类型参数必须有一个公有、无参的构造函数。当于其它约束联合使用时,new()约束必须放在最后。

    where T : <base class name>

    类型参数必须是指定的基类型或是派生自指定的基类型。

    where T : <interface name>

    类型参数必须是指定的接口或是指定接口的实现。可以指定多个接口约束。接口约束也可以是泛型的。

                                       

     

    类型参数的约束,增加了可调用的操作和方法的数量。这些操作和方法受约束类型及其派生层次中的类型的支持。因此,设计泛型类或方法时,如果对泛型成员执行任何赋值以外的操作,或者是调用System.Object中所没有的方法,就需要在类型参数上使用约束。

     

     

    无限制类型参数的一般用法

    没有约束的类型参数,如公有类MyClass<T>{...}中的T, 被称为无限制类型参数(unbounded type parameters)。无限制类型参数有以下规则:

    1.        不能使用运算符 != 和 == ,因为无法保证具体的类型参数能够支持这些运算符。

    2.        它们可以与System.Object相互转换,也可显式地转换成任何接口类型。

    3.        可以与null比较。如果一个无限制类型参数与null比较,当此类型参数为值类型时,比较的结果总为false。

     

     

    无类型约束

    当约束是一个泛型类型参数时,它就叫无类型约束(Naked type constraints)。当一个有类型参数成员方法,要把它的参数约束为其所在类的类型参数时,无类型约束很有用。如下例所示:

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

    在上面的示例中, Add方法的上下文中的T,就是一个无类型约束;而List类的上下文中的T,则是一个无限制类型参数。

     

    无类型约束也可以用在泛型类的定义中。注意,无类型约束一定也要和其它类型参数一起在尖括号中声明:

    //naked type constraint
    public class MyClass<T,U,V> where T : V

    因为编译器只认为无类型约束是从System.Object继承而来,所以带有无类型约束的泛型类的用途十分有限。当你希望强制两个类型参数具有继承关系时,可对泛型类使用无类型约束。

     

  • 相关阅读:
    我真的没读野鸡大学!是他们不好好起名字!
    Request.Cookies和Response.Cookies
    深受理科生喜欢的10大专业
    如何玩转“互联网+教育”?
    js调试工具Console命令详解
    XSS获取cookie并利用
    257. Binary Tree Paths
    EXEC sp_executesql with multiple parameters
    235. Lowest Common Ancestor of a Binary Search Tree
    226. Invert Binary Tree
  • 原文地址:https://www.cnblogs.com/XiaoRuLiang/p/12422207.html
Copyright © 2020-2023  润新知