文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C# in depth 2nd 读后感(四) 泛型

C# in depth 2nd 读后感(四) 泛型

时间:2010-12-27  来源:菜鸟老了

姓名:泛型(这是一个很多人共同拥有的名字,貌似他们来自相同的父母)

性别:未知(由于具有高超的易容术)

父母:又小又软的家伙,曰微软(名不副实啊);

出生地:C#2.0

特征:在屁股后面总是跟着两个相互看不顺眼的小屁孩:"<"&&">";(就像五行不仅相克而且相生一样,当<和>联手时,可包容万象---来自万王之王object);

性格:对于爱情至死不渝,结婚后从不考虑离婚,即使有其他类型主动投怀送抱也坚决不从,誓死抗争。及其鄙视像ArrayList这种水性杨花的人。

下面试ArrayList和泛型(List<T>读作list of T)的性格对比:

例一:
ArrayList _list=new ArrayList();
_list.Add(
10);
_list.Add(
"try");//由于ArrayList的Add方法的参数类型为object所以添加不同类型的参数不会出错。
foreach(string s in _list)//编译通过,但是运行时10在强制转换成string时出错
{
...
}
List
<string> list=new List<string>();
list.Add(
"try");
list.Add(
10);//编译不通过

优点:使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。(使用泛型可以极大的减少装箱和拆箱操作,并且可以让程序员把注意力更多的转向业务流程而不是数据类型)。

名言:用我吧!

 

ps:好吧 我真的不知道怎么开头。

二:泛型声明

泛型类声明如下:

class GenericClass<T> where T : class,new(){        public void GetValue<U>() { }//这个T将GenericClass<T>中的T覆盖,所以又warning。建议用其他参数U替代以免混淆。
public T GetValue()
{
T _value;
_value = data;
return _value;
}
public GenericClass(T message)
{
data = message;
}

private T data;
public override string ToString()
{
return "data :" + data;
}
}

其中,GenericClass<T>为泛型类名,T为泛型参数,where 后面定义T的约束条件。

注意GetValue<U>()里的这个U,如果把U改成T,那么编译器会提示错误。因为这个T和类声明里面的那个T是不一样的,并且在方法中会将GenericClass<T>中的T隐藏掉。

如:

代码
定义:
class GenericClass<T>// where T : class,new()
{

public void GetValue<T>() { Console.WriteLine(typeof(T)); }
}

实现:

GenericClass
<string> gc = new GenericClass<string>("try");
gc.GetValue
<int>();
输出:
System.Int32

 在进行泛型命名时,应避免不同泛型类型采用相同名称的命名(如上)。

 

三、约束条件

如上,where T 后接泛型类型的约束条件。如下式MSDN上关于泛型约束条件的说明

约束 说明

<1>T:结构

类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。有关更多信息,请参见使用可空类型(C# 编程指南)

<2>T:类

类型参数必须是引用类型,包括任何类、接口、委托或数组类型。

<3>T:new()

类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。

<4>T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

<5>T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。

<6>T:U

为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束。

 

其中,<1><2>两种限定条件可以不存在,但是如果存在只能有一种。并且需放在其他约束条件之前。<3>约束条件只能放在最后。<4><5><6>约束条件可以有多个。

 

例二
Valid
class Sample<T> where T : class, IDisposable, new()
class Sample<T> where T : struct, IDisposable
class Sample<T,U> where T : class where U : struct, T
class Sample<T,U> where T : Stream where U : IDisposable
Invalid
class Sample<T> where T : class, struct
class Sample<T> where T : Stream, class
class Sample<T> where T : new(), Stream
class Sample<T> where T : IDisposable, Stream
class Sample<T> where T : XmlReader, IComparable, IComparable
class Sample<T,U> where T : struct where U : class, T
class Sample<T,U> where T : Stream, U : IDisposable

 

 

虽然说class Sample<T,U> where T : class where U : struct, T的约束条件使用起来很别扭,但是当T是Object或接口而U是T的派生类时,Sample<T,U>可进行实例化:

 

Sample<IComparable, DateTime> _sample=new Sample<Icomparable,DateTime>();

 

 

四、泛型与反射

这个比较简单,可以根据反射来获取我们实例化后的参数的类型:

如:

class TypeGeneric<T>

{

void GetTypeOfT()
{

Console.WriteLine(typeof(T));

}

}

这时,当我们的用int作为参数类型时,输出System.Int32。

 

ps:这篇文章写得很痛苦


排行榜 更多 +
白银之城手游官服下载

白银之城手游官服下载

角色扮演 下载
像素赛车手魔改版下载

像素赛车手魔改版下载

赛车竞速 下载
全民摆摊免广告版下载

全民摆摊免广告版下载

模拟经营 下载