在概念泛型类时,能够对客户端代码能够在实例化类时用来项目参数的类型种类施加限制。借使客户端代码尝试利用某些约束所不容许的门类来实例化类,则会发出编写翻译时不当。那几个限制称为约束。约束是行使
where 上下文关键字钦点的。下表列出了八种档案的次序的自律:

自律表达

概念泛型类时,能够对客户端代码能够在实例化类时用来项目参数的几系列型施加限制。
假诺客户端代码尝试使用约束所不允许的体系来实例化类,则会产生编译时不当。
那几个限制称为约束。 通过采纳 where 上下文关键字钦赐约束。
下表列出了陆体系型的束缚:

约束 描述
where T:结构 类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。 有关详细信息,请参阅使用可以为 null 的类型
where T:类 类型参数必须是引用类型;这同样适用于所有类、接口、委托或数组类型。
where T:new() 类型参数必须具有公共无参数构造函数。 与其他约束一起使用时,new() 约束必须最后指定。
where T:<基类名称> 类型参数必须是指定的基类或派生自指定的基类。
where T:<接口名称> 类型参数必须是指定的接口或实现指定的接口。 可指定多个接口约束。 约束接口也可以是泛型。
where T:U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。

啊.紫原文C#
泛型类型参数的封锁

T:结构
种类参数必须是值类型。能够钦定除 Nullable
以外的此外值类型。有关越来越多新闻,请参见使用可空类型(C# 编制程序指南)。

运用约束的缘由

即使要检查泛型列表中的有个别项,鲜明它是否行得通,也许将它与其它有些项进行相比较,则编译器必须保证它供给调用的运算符或措施将倍受客户端代码只怕钦赐的其他类型参数的援救。
通过对泛型类定义应用2个或多少个约束得到那种保障。
举例,基类约束告诉编写翻译器,仅此类型的靶子或派生自此类型的靶子可用作类型参数。
编写翻译器有了此保证后,就能够允许在泛型类中调用该项目标办法。 通过使用
where 上下文关键字采纳约束。
以下代码示例演示可经过应用基类约束加多到(泛型介绍中的)GenericList<T>
类的机能。

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.Name 属性,因为品种 T 的持有项都保险是
Employee 对象大概从 Employee 承接的靶子。
能够对同一等级次序参数应用四个约束,并且封锁本身能够是泛型类型,如下所示:

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);
}

并发这种场所是因为,编写翻译器在编写翻译时仅知道 T
是引用类型,因而必须运用对具备引用类型都有效的私下认可运算符。
如若必须测试值相等性,提议的章程是还要利用where T : IComparable<T>封锁,并在将用于协会泛型类的别的类中贯彻该接口。

在概念泛型类时,能够对客户端代码能够在实例化类时用于项目参数的花色种类施加限制。如若客户端代码尝试利用某些约束所差别意的档期的顺序来实例化类,则会发出编译时不当。那些限制称为约束。约束是选拔 where 上下文关键字钦点的。下表列出了6体系型的羁绊:

T:类
花色约束,类型参数的自律。品种参数必须是援引类型,蕴涵任何类、接口、委托或数组类型。

自律五个参数

能够对几个参数应用四个约束,对1个参数应用三个约束,如下例所示:

class Base
{
}
class Test<T, U> where U : struct where T : Base, new()
{
}
where T: struct
类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。有关更多信息,请参见使用可以为 null 的类型(C# 编程指南)。
where T : class
类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。
where T:new()
类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。
where T:<基类名>
类型参数必须是指定的基类或派生自指定的基类。
where T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
where T:U
为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。

T:new()
项目参数必须持有无参数的公物构造函数。当与其它约束共同利用时,new()
约束必须最终钦点。

未绑定的门类参数

从没约束的花色参数(如公共类 SampleClass<T>{} 中的
T)称为未绑定的等级次序参数。 未绑定的体系参数具备以下规则:

  • 不能使用 != 和 ==
    运算符,因为不能够保障具体的品种参数能辅助那一个运算符。
  • 能够在它们与 System.Object
    之间来回调换,或将它们显式调换为其它接口类型。
  • 能够将它们与
    null
    实行比较。 将未绑定的参数与 null
    实行相比时,尽管类型参数为值类型,则该比较将始终重回 false。

选用约束的案由

 

假使要检查泛型列表中的某些项以明确它是或不是行得通,可能将它与其他某个项进行比较,则编写翻译器必须在任其自流程度上确定保障它须要调用的运算符或艺术将遭到客户端代码大概钦赐的别的项目参数的支撑。那种保证是通过对泛型类定义应用三个或四个约束得到的。比如,基类约束告诉编写翻译器:仅此类型的目的或将来类型派生的靶子才可用作类型参数。1旦编写翻译器有了那么些保障,它就能够允许在泛型类中调用该项目标法门。约束是使用上下文关键字 where 应用的。

金沙注册送58 1金沙注册送58 2

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;
    }
}

View Code

自律使得泛型类能够采取Employee.Name 属性,因为品种为 T 的有所项都保险是 Employee 对象或从
Employee 承接的对象。

能够对同样类别参数应用三个约束,并且封锁自个儿能够是泛型类型,如下所示:

 

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

 

经过自律类型参数,能够增加约束类型及其承接等级次序结构中的全数品种所支撑的允许操作和章程调用的多少。因而,在打算泛型类或措施时,借使要对泛型成员推行除轻易赋值之外的其余操作或调用 System.Object 不协助的其他格局,您将急需对该类型参数应用约束。

在应用 where
T : class 约束时,防止对项目参数使用 == 和 != 运算符,因为这么些运算符仅测试引用同一性而不测试值相等性。就算在作为参数的档期的顺序中重载那几个运算符也是那样。上面包车型客车代码表达了那或多或少;固然 String 类重载 == 运算符,输出也为
false。

 

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);
}

 

那种情状的原由在于,编写翻译器在编写翻译时仅知道
T 是援引类型,因而必须利用对具备引用类型都灵验的暗许运算符。假设非得测试值相等性,建议的艺术是同时使用 where
T :
IComparable<T> 约束,并在将用来组织泛型类的别的类中落到实处该接口。

 

T:<基类名>
花色参数必须是钦点的基类或派生自钦定的基类。

品类参数作为约束

在具有温馨类型参数的积极分子函数必须将该参数约束为带有类型的花色参数时,将泛型类型参数作为约束非常有用,如下例所示:

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

在上述示范中,T 在 Add 方法的上下文中是一个品种约束,而在 List
类的左右文中是二个未绑定的类型参。
花色参数还可在泛型类定义中作为约束。
请注意,必须在尖括号中宣示此类型参数以及别的其它连串参数:

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

花色参数作为泛型类的约束的功用11分有限,因为编写翻译器除了要是类型参数派生自
System.Object 以外,不会做任何任何借使。
要是要在四个门类参数之间强制承接关系,能够将品种参数用作泛型类的封锁。

封锁八个参数

可以对五个参数应用约束,并对1个参数应用几个约束,如上面包车型客车以身作则所示:

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

T:<接口名称>
项目参数必须是点名的接口或落到实处钦赐的接口。能够钦命四个接口约束。约束接口也能够是泛型的。

未绑定的等级次序参数

尚未约束的品类参数(如公共类 萨姆pleClass<T>{} 中的
T)称为未绑定的门类参数。未绑定的门类参数具备以下规则:

不可能接纳 != 和 == 运算符,因为不能确认保证具体品种参数能支撑那些运算符。

金沙注册送58 ,可以在它们与 System.Object
之间来回调换,或将它们显式变换为其余接口类型。

能够将它们与 null 进行相比。将未绑定的参数与 null
举行相比时,假如类型参数为值类型,则该比较将始终重返 false。

T:U
为 T 提供的项目参数必须是为 U 提供的参数或派生自为 U
提供的参数。那叫做裸类型约束。

用作约束的连串参数

将泛型类型参数作为约束使用,在富有本人类型参数的分子函数必须将该参数约束为涵盖类型的品种参数时10分有用,如下示例所示:

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

在上边的演示中,T 在 Add 方法的左右文中是二个品种约束,而在 List 类的内外文中是一个未绑定的品种参数。

连串参数还可在泛型类定义中作为约束。请小心,必须在尖括号中声称此类型参数与其余别的门类的参数:

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

 

泛型类的项目参数约束的效率10分有限,因为编写翻译器除了借使类型参数派生自 System.Object 以外,不会做别的任何若是。在期待强制八个档期的顺序参数之间的接续关系的情状下,可对泛型类使用参数类型约束。

 

 

 

选拔约束的来头

假定要反省泛型列表中的有些项以明确它是不是管用,可能将它与别的某些项实行相比,则编写翻译器必须在自然水准上确定保障它必要调用的运算符或艺术将受到客户端代码也许钦命的别样项目参数的帮助。那种保障是通过对泛型类定义应用三个或五个约束得到的。举例,基类约束告诉编写翻译器:仅此类型的对象或之后类型派生的目的才可用作类型参数。一旦编写翻译器有了那些有限协助,它就能够允许在泛型类中调用该类型的秘诀。约束是应用上下文关键字
where 应用的。下边包车型客车代码示例演示可由此接纳基类约束增多到 GenericList

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;  
    }  
}  

因而自律类型参数,能够扩张约束类型及其承接档次结构中的全体品种所支撑的同意操作和措施调用的数据。因而,在计划泛型类或艺术时,若是要对泛型成员试行除轻松赋值之外的别的操作或调用
System.Object 不帮助的其余措施,您将索要对该项目参数应用约束。
在应用 where T : class 约束时,建议不用对项目参数使用 == 和 !=
运算符,因为这几个运算符仅测试引用同一性而不测试值相等性。即便在作为参数的品种中重载这个运算符也是这么。下边包车型的士代码表达了这点;就算String 类重载 == 运算符,输出也为 false。

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);  
}  

这种景色的因由在于,编写翻译器在编写翻译时仅知道 T
是援引类型,由此必须运用对全部引用类型都有效的私下认可运算符。若是急需测试值相等性,建议的格局是还要采取where T : IComparable

不曾约束的类型参数(如公共类 萨姆pleClass

裸类型约束

作为约束的泛型类型参数称为裸类型约束。当有着友好的体系参数的成员函数供给将该参数约束为含有类型的种类参数时,裸类型约束很有用,如下边包车型地铁示范所示:

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

在上边的演示中,T 在 Add 方法的左右文中是二个裸类型约束,而在 List
类的光景文中是四个未绑定的等级次序参数。
裸类型约束还足以在泛型类定义中利用。注意,还必须已经和其它任何项目参数一齐在尖括号中证明了裸类型约束:

//naked type constraint  
public class SampleClass<T, U, V> where T : V { }  

泛型类的裸类型约束的成效相当简单,因为编写翻译器除了如若有些裸类型约束派生自
System.Object
以外,不会做其余任何即使。在盼望强制五个类型参数之间的持续关系的情景下,可对泛型类使用裸类型约束。

相关文章

网站地图xml地图