• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#泛型与泛型约束

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

为什么要使用泛型

考虑一种堆栈类

 class Stack
    {
        public string[] Elements { get; set; }
        public int Current { get; set; }
        public string Pop()
        {
            return Elements[Current];
        }
        public void Push(string element)
        {
        }
    }

上述堆栈类的元素是字符串类型,但实际开发中可能运用到很多不同的类型,甚至是自定义的类型。显然我们不可能为每一个类型新建一个“Stack”类。


简单的泛型应用

泛型类型参数

在C++模板中,使用“T”代表一个模板类型。这种用法同样延续到了C#中。
此外,还可以以T开头选择更加符合语境的词语,例如:
Dictionary<TKey,TValue>。
在泛型类型或泛型方法定义中,使用"T",以“T”为前缀的描述性词语,作为该泛型的类型参数更加符合规范。

泛型在类中

对于上述的Stack类,可以改写为如下形式

 class Stack<TElement>
    {
        public TElement[] Elements { get; set; }
        public int Current { get; set; }
        public TElement Pop()
        {
            return Elements[Current];
        }
        public void Push(string element)
        {
        }
    }

泛型在接口中

泛型在接口中广泛运用,特别是泛型集合类。
在System.Collections.Generic下存在大量泛型接口

泛型在接口中的简单使用如下:

interface IInterface<T>
    {
        void fun1(T t);
        T fun2();
    }

泛型在方法中

泛型也可以在方法中使用,代表一个使用类型参数声明的方法。
代码示例

public void Swap<T>(ref T lhs,ref T rhs)
        {
            
        }

泛型约束

定义泛型时,可以对泛型类或泛型接口,方法能够接收的类型参数的种类加以限制。在编译阶段,如果使用不符合要求的类作为类型参数,则会产生编译错误。

泛型约束的声明格式

使用where关键字指定泛型约束

泛型约束使用where关键字指定。例如,要限制一个泛型类必须具有无参数公共构造函数,代码如下:

class Stack<TElement> where TElement :new()
六种约束的格式说明

where T:struct

class Stack<TElement> where TElement :struct

限制类型参数必须是值类型,并且不可以是可空值类型(例如int?,char?,double?,bool?等)
where T: class

class Stack<TElement> where TElement :class

限制类型参数必须是引用类型
where T:基类名

class Stack<TElement> where TElement :BaseClass

限制类型参数必须是继承自指定的基类,或是基类本身
where T:接口名

class Stack<TElement> where TElement :IInterface

限制类型参数必须是实现指定接口,或是指定接口
where T:new()

class Stack<TElement> where TElement :new()

限制类型参数必须具有无参构造函数

泛型约束的意义

泛型约束可以保证传递的类型参数符合一定的条件,并且在编译阶段就可以进行验证:例如添加T: new()约束可以保证传递的类型参数一定包含无参构造函数,添加基类约束可以保证类型一定派生自某个基类。
有了上面的保证,我们就可以在泛型类中调用T类型的构造函数,或者调用其基类的方法。
例如:

为Stack类添加约束
(注意构造器约束需要放在最后)

 public class Stack<TElement> where TElement :Paper,new()
{
        public TElement[] Elements { get; set; }
        public int Current { get; set; }
        public Paper Pop()
        {
            TElement element = new TElement();
            element = Elements[Current];
            return element.DrawOutTissue();
        }
        public void Push(string element)
        {
        }
    }
 public class Paper
{
        Paper()
        {
        }
        Paper DrawOutTissue()
        {
            return new Paper();
        }
    }

泛型约束的一些复杂情况

多个约束

对一个泛型参数可以添加多个约束,例如,可以同时为上述”class Stack “ 添加 class,new(),Paper,
但是:

  • 不可能同时添加struct和class约束
  • 不可能添加多个基类约束
  • 约束之间是 and 关系,不能添加or关系的约束
  • 构造器约束必须最后
  • 构造器约束只能指明无参构造器
  • 约束不会继承
多个参数

对于一种表示“键值对”关系的泛型类KeyValue<TKey,TValue>,该类具有两个泛型参数TKey,TValue,要为其都添加约束,代码如下:

public class KeyValue<TKey,TValue> where TKey : new() 
                                                where TValue: Base,new()

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C# 将数据导出到Excel汇总Webform,Winform(转)发布时间:2022-07-14
下一篇:
C#解压或压缩文件夹 - 韩显川发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap