C#泛型

转自

http://hi.baidu.com/brady_home/blog/item/53a36809d68780aa2fddd467.html

 

有朋友请我给他写些关于泛型的资料,所以就趁现在有时间,写出来。。
一、泛型简介
1.1泛型

通过使用泛型,可以创建这样的类、接口和方法,它们以一种类型安全的工作方式操作各种数据。
本质上,术语“泛型”指的是“参数化类型”(parameterized types)。参数化类型非常重要,因为它们可以在创建类、接口、方法和委托的时候将要操作的数据类型作为参数进行指定。
通过泛型,可以创建一个类,使其自动处理不同类型的数据。使用参数化类型的类、接口、方法和委托都可以称为“泛型”。
可以通过使用object类型的引用来创建通用的类、接口、方法和委托。但这种方法的缺陷在于,无法保证类型安全。泛型弥补了无法保证类型安全的缺陷,也简化了处理的过程。因为不再需要执行object与实际操作的数据类型之间的转换。
因此,泛型可以使开发人员最大限度地重用代码,并使得代码更加简单,更加安全。

泛型类型因类型参数的不同而不同。
理解泛型类型的一个关键在于,对某个泛型类型的一个版本的引用并不能与同一泛型类型的另一个版本相兼容。


1.2泛型如何实现类型安全?
泛型可以自动确保有关的泛型类的所有操作都是类安全的。在处理过程中,泛型避免了手工进行转换和编写类型检查代码的必要。

1.3泛型类的通用形式:
class class-name<type-param-list>{}
声明一个对泛型类的引用的语法:
class-name<type-arg-list> var-name=new class-name<type-arg-list>(cons-arg-list);
举例:
class GenericClass<T, V>
{
        T data;
//declare an object of type T
        V data2;       
        public GenericClass(T obT, V ob2)
        {
            data1 = ob1;
            data2 = ob2;
        }
        public T GetData()
        {
            return this.data;
        }
        public void ShowType()
        {
            Console.WriteLine("The type of T is : {0},The type of V is:{1}",typeof(T),typeof(V));
        }
}

在实际应用中,我们往往会对类型T进行一定的约束,以限制应用区域。


二、类型约束(Constrained types)

2.1类型约束(Constrained types)
在指定一个类型参数时,可以指定类型参数必须满足的约束条件。这是通过在指定类型参数时使用where子句来实现的。
class class-name<type-param> where type-param:constraints{}
其中constraints是一个逗号分割的约束列表。

2.2五种约束类型
(1)可以使用“基类约束”(base class constraint)来指定某个基类必须出现在类型实参中。这种约束是通过指定基类名称来实现的。
(2)可以使用“接口约束”(interface constraint)来指定某个类型实参必须实现一个或多个接口。这种约束是通过指定接口名称来实现的。
(3)可以要求类型实参必须提供一个无参数的构造函数,这被称为“构造函数约束”(constructor constraint)。它是通过new()指定的。
(4)可以通过关键字class指定“引用类型约束”(reference type constraint)来限制某个类型实参必须是引用类型。
(5)可以通过关键字struct指定“值类型约束”(vlaue type constraint)来限制某个类型实参必须是值类型。
2.2.1 基类约束
使用基类约束,我们可以指定某个类型实参必须继承的基类。
基类约束有两个功能:
(1)它允许在泛型类中使用由约束指定的基类所定义的成员。例如,可以调用基类的方法或者使用基类的属性。如果没有基类约束,编译器就无法知道某个类型实参拥有哪些成员。通过提供基类约束,编译器将知道所有的类型实参都拥有由指定基类所定义的成员。
(2)确保类型实参支持指定的基类类型参数。这意味着对于任意给定的基类约束,类型实参必须要么是基类本身,要么是派生于该基类的类,如果试图使用没有继承指定基类的类型实参,就会导致编译错误。
基类约束使用下面形式的where子句:
where T:base-class-name
T是类型参数的名称,base-class-name是基类的名称,这里只能指定一个基类。

2.2.2 接口约束
接口约束用于指定某个类型参数必须应用的接口。接口的两个主要功能和基类约束完全一样。
基本形式 where T:interface-name
interface-name是接口的名称,可以通过使用由逗号分割的列表来同时指定多个接口。
如果某个约束同时包含基类和接口,则先指定基类列表,再指定接口列表。

2.2.3 new()构造函数约束
new()构造函数约束允许开发人员实例化一个泛型类型的对象。
一般情况下,我们无法创建一个泛型类型参数的实例。然而,new()约束改变了这种情况,他要求类型参数必须提供一个无参数的构造函数。
在使用new()约束时,可以通过调用该无参构造函数来创建对象。
基本形式: where T : new()
使用new()约束时应注意两点:
(1)它可以与其他约束一起使用,但是必须位于约束列表的末端。
(2)new()仅允许开发人员使用无参构造函数来构造一个对象,即使同时存在其他的构造函数。换句话说,不允许给类型参数的构造函数传递实参。

2.2.4 引用类型和值类型约束
如果引用类型和值类型之间的差别对于泛型代码非常重要,那么这些约束就非常有用。
基本形式:
where T : class
where T : struct
若同时存在其他约束的情况下,class或struct必须位于列表的开头。

另外可以通过 使用约束来建立两个类型参数之间的关系
例如 class GenericClass2<T, V> where V:T{} -------- 要求V必须继承于T,这种称为裸类型约束(naked type constraint)

举例:
class BaseC
{
        int baseInt;
        string baseStr;
        public void Show()
        {
            Console.WriteLine("Something");
        }
}
//基类约束
class GenericClass3<T> where T : BaseC
{
        T ob1;
        public void Show()
        {
            ob1.Show();
        }
}
//new()构造函数约束
class GenericClass4<T> where T : new()
{
        public T ob1;
        public GenericClass4()
        {
            ob1 = new T();
        }
}


三、使用泛型类

在给泛型类传递类型实参的时候,实际创建的是C#中的“封闭构建类型”(closed constructed type)。
术语“封闭”一词,是指指定了类型实参,因此GenericClass<int>是一个封闭构建类型。
本质上,泛型类型,例如GenericClass<T>,是一种抽象结构。只有在特定的版本(例如GenericClass<int>)被构建以后才创建了一个实际的类型。
在C#中术语中,GenericClass<T>之类的构造被称为“开放构建类型”(open constructed type),是因为他没有指定类型实参。
举例:
public void Demo1()
{
       GenericClass<int,string> gen=new GenericClass<int,string>(12,"I am Chinese"); 
       Console.Write("Type: ");
       gen.ShowType();
       Console.WriteLine("The first Data: " + gen.GetData());
}
//new()构造函数约束
public void Demo2()
{
       GenericClass4<BaseC> demo4 = new GenericClass4<BaseC>();
       demo4.ob1.Show();
}

好了。我所知道的关于泛型的知识就想到这么多。。
请大家多指正。。先谢谢哈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值