zoukankan      html  css  js  c++  java
  • 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!

  • 相关阅读:
    网站添加手机短信功能
    FileWriter的正确使用,请及时关闭流
    myeclipse9.0没有提示
    Integer.getInteger,are you kinding me? 好吧, 我还是没怎么弄明白,求高人解答。。。
    构造方法充当临时对象&Calendar的使用
    关于Spring IOC的一点个人理解
    在JAVA中使用GUID
    动态生成table下的<tr>标签不显示
    MD5加密实例
    String,StringBuffer 和 StringBuilder 的区别
  • 原文地址:https://www.cnblogs.com/sjqq/p/6910612.html
Copyright © 2011-2022 走看看