C#泛型约束

本文将对各类泛型约束做一个简单的总结。

文章一开始,给出演示代码底稿(在此基础上修改,演示,说明。)

class MyList<T>
{
    List<T> list = new List<T>();
    public T this[int i]
    {
        get { return list[i]; }
        set { this.list[i] = value; }
    }
}

class Person
{
    public string Name { get; set; }
}

接下来,依次修改演示代码底稿,来说明不同类型的泛型约束。

1 指定泛型参数为值类型

class MyList<T> where T:struct
{
...代码省略部分
}

看看加上约束后的效果怎么样,按下面方式 实例化MyList 类 :

MyList<Person> list = new MyList<Person>();

你会发现,将产生如下错误提示:

类型“GencConstraint.Person”必须是不可为 null 的值类型才能用作泛型类型或方法“GencConstraint.MyList<T>”中的参数“T”。

使用下面的方式实例化MyList 类 ,将一切正常:

MyList<int> list = new MyList<int>();

2  指定泛型参数为引用类型

class MyList<T> where T:class
{
...代码省略部分
}

修改泛型约束为 引用类型后,前面的错误提示消失,因为 Person 类是引用类型,满足泛型约束。

3  指定泛型参数有无参的公共的构造函数

class MyList<T> where T:new()
{
...代码省略部分
}

为Person类增加私有的无参构造函数,代码如下:

class Person
{
    public string Name { get; set; }
    private Person()
    {
        //do nothing
    }
}

实例化 MyList < Person > 类:

MyList<Person> list = new MyList<Person>();

出现编译错误,提示:

“GencConstraint.Person”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法“GencConstraint.MyList<T>”中的参数“T”。

哈哈,约束起作用了。

4  指定泛型参数 必须派生于指定基类

增加抽象类 SeniorAnimal

abstract class SeniorAnimal//高级动物
{
    public abstract void Speak();//会说话
    public abstract void UseTool();//会使用工具
}

指定泛型参数 必须派生于基类 SeniorAnimal

class MyList<T> where T : SeniorAnimal
{
     ...代码省略部分
}

实例化 MyList < Person > 类(此时Person类还未继承自 SeniorAnimal 类 ):

MyList<Person> list = new MyList<Person>();

出现编译错误,提示:

不能将类型“GencConstraint.Person”用作泛型类型或方法“GencConstraint.MyList<T>”中的类型参数“T”。没有从“‘GencConstraint.Person”到“GencConstraint.SeniorAnimal”的隐式引用转换。

修改代码,使Person类继承自 SeniorAnimal 类

class Person : SeniorAnimal
{
    public string Name { get; set; }

    public override void Speak()
    {
        Console.WriteLine("我会说脏话!");
    }

    public override void UseTool()
    {
        Console.WriteLine("我会用砍刀!");
    }
}

再次编译,一切正常。

5 指定泛型参数 必须实现指定接口

演示情况和第4点类似,就不提供演示代码了。

6  指定泛型参数 必须派生于泛型类型U(裸类型约束)

class MyList<U> where U : SeniorAnimal
{
    List<U> list = new List<U>();
    public void ShowInfo<T>() where T : U
    {
    }
}

另外,可以为同一泛型参数应用多个约束。

好了,Game Over!

时间: 2024-12-15 01:53:14

C#泛型约束的相关文章

泛型约束

-----------------------------------IDocument.cs(定义一个接口) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 {     public interface IDocument     {         s

C# where泛型约束与new

最近无意中看到了:http://msdn.microsoft.com/zh-cn/library/bb384067.aspx.但是,人笨啊,木有看懂到底是啥意思,木办法自己写一个试试吧,权当做个笔记 例子如下: 接口: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WhereTest { /// <summary> /// 水果接口 /// <

转:C# 泛型编程之泛型类、泛型方法、泛型约束

C# 泛型编程之泛型类.泛型方法.泛型约束 分类: asp.net c#2012-08-07 17:36 5998人阅读 评论(0) 收藏 举报 c#编程classobject编译器struct 泛型方法 在C#2.0中,方法可以定义特定于其执行范围的泛型参数,如下所示: public class MyClass<T>    {        //指定MyMethod方法用以执行类型为X的参数        public void MyMethod<X>(X x)         

C# 泛型编程之泛型类、泛型方法、泛型约束

所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型. 泛型编程是一种编程范式,它利用"参数化类型"将类型抽象化,从而实现更为灵活的复用.在定义泛型类时,在对客户端代码能够在实例化类时,可以用类型参数的类型种类施加限制. 泛型方法 在C# 2.0中,方法可以定义特定于其执行范围的泛型参数,如下所示: public class MyClass<T> { //指定MyMethod方法用以执行类型为X的参数 public void MyMethod<X>(X

泛型约束和利用反射修改对象属性的值

周日了都,昨天休息了一天,今天想想得敲敲代码练习一下,如下关于泛型约束和利用反射修改对象属性的值的, 都挺简单的,呵呵,但时间一长,不经常使用还容易忘记在此就当记录一下了, 首先泛型代码一般是如下的情形: 加了泛型约束,只允许引用类型并且是只能是无参数的构造函数的类型才能传入,也就是不允许给类构造参数传递实参,否则将报错. 错误 1 “XXXXXX.pros”必须是具有公共的无参数构造函数的非抽象类型,才能用作泛型类型或方法“ 1 public static T GetObject<T>(T

.Net 泛型约束

本文内容 使用泛型约束的原因 未绑定的类型参数 作为约束的类型参数 参考资料 当“设计模式”出现时,人们提“用接口编程”:后来,有了泛型,人们提“用泛型编程”.什么泛型?比如,单链表 LinkedList 场景,每个节点包含两个字段:值和下一个节点的引用,其中,“值”既可以是 int,也可以是 string,甚至是对象,为每个数据类型都写一个类,显然太麻烦,此时就可以使用泛型 LinkedList <T>,T 表示 int 或 string 类型等等:再如,排序算法中很常见 Swap(ref

06.C#泛型约束和高级泛型(三章3.3-3.4)

吃午饭前继上篇泛型再写一篇关于泛型的文章,虽然总是被博客园移出首页,文章不精确实是大问题啊,会再接再厉的.进入正题. 先来说下泛型约束.当我们在使用泛型的时候通常会希望使用泛型实参时,参数能具备某一些特性,这时"泛型约束"来了,它能帮助我们在传入泛型参数,该参数要实现先前指定的约束.有4种约束可用,如下: 引用类型约束:确保使用的类型参数是引用类型(T:class,且必须是类型参数指定的第一个约束),类型实参任何类.接口.数组.委托.或者已知是引用类型的另一个类型参数. 值类型约束:表

C# 泛型约束 xxx&lt;T&gt; Where T:约束(一)

发现我们游戏的代码中,主程写了很多类似这样的代码: public static T CreateObject<T>(out int objectId) where T : new() //方法名 public class CSingleton<T> where T : new() //单例类 public T GetControl<T>(string uri, Transform findTrans = null, bool isLog = true) where T

通过另类的泛型约束将两个输入输出参数不同的方法合并成一个方法的实现

其实我也不知道如何定义这个标题,词乏,姑且先这样定义吧. 看了本文章的朋友,如果有更好标题,请告诉我,谢谢. 有个项目使用SDK时遇到这样一个情况. 该SDK有个BtPrinterManager类,拥有两个方法:ServerPrint和ClientPrint,这两个方法有一部分参数是一样的,一部分参数不一样. 现在我们要对这个类进行封装,把这两个方法合并成一个方法,并且使其拥有相同的输入参数和输出参数. 比较粗糙的做法是,把这两个方法的输入参数合并成一个输入模型类,把两个方法的输出参数也合并成一