马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
捆绑编译器。用户不需要受制于厂家,自己就能将程序在新平台上编译运行。除了牛B轰轰的linux,估计也没有系统捆绑c/c++的编译器,而且许多新平台都无法支持复杂的c/c++编译器在上面直接运行。visual 甚么是泛型
一品种型占位符,或称之为范例参数。我们晓得在一个办法中,一个变量的值能够作为参数,但实在这个变量的范例自己也能够作为参数。泛型同意我们在挪用的时分再指定这个范例参数是甚么。在.net中,泛型可以给我们带来的两个分明优点是――范例平安和削减装箱、拆箱。
范例平安和装箱、拆箱
作为一品种型参数,泛型很简单给我们带来范例平安。而在之前,在.net1.1中我们要完成范例平安能够如许做:
//假定你有一团体员汇合
publicclassPerson{
privatestring_name;
publicstringName
{get{return_name;}
set{_name=value;}}
}
//假定你有一团体员汇合
publicclassPersonCollection:IList
{
...
privateArrayList_Persons=newArrayList();
publicPersonthis[intindex]
{get{return(Person)_Persons[index];}}
publicintAdd(Personitem)
{_Persons.Add(item);
return_Persons.Count-1;}
publicvoidRemove(Personitem)
{_Persons.Remove(item);}
objectIList.this[intindex]
{get{return_Persons[index];}
set{_Persons[index]=(Person)value;}}
intIList.Add(objectitem)
{returnAdd((Person)item);}
voidIList.Remove(objectitem)
{Remove((Person)item);}
...
}
上述代码次要接纳了显性接口成员(explicitinterfacememberimplementation)手艺,可以完成范例平安,但成绩是:
・发生反复代码。假定你另有一个Dog类汇合,其功效不异,但为了范例平安,你必需要Copy一份代码,如许便使程序反复代码增添,劈面对变更的时分,更难保护。
publicclassDogCollection:IList
{
...
privateArrayList_Dogs=newArrayList();
publicDogthis[intindex]
{get{return(Dog)_Dogs[index];}}
publicintAdd(Dogitem)
{_Dogs.Add(item);
return_Dogs.Count-1;}
publicvoidRemove(Dogitem)
{_Dogs.Remove(item);}
objectIList.this[intindex]
{get{return_Dogs[index];}
set{_Dogs[index]=(Dog)value;}}
intIList.Add(objectitem)
{returnAdd((Dog)item);}
voidIList.Remove(objectitem)
{Remove((Dog)item);}
...
}
假如在泛型中,要完成范例平安,你不必要拷贝任何代码,你仅仅必要如许做:
List<Person>persons=newList<Person>();
persons.Add(newPerson());
Personperson=persons[0];
List<Dog>dogs=newList<Dog>();
dogs.Add(newDog());
Dogdog=dogs[0];
・关于值范例的工具仍是必要分外的装箱、拆箱。实在关于传统的汇合来讲,只需个中的包括的内容触及到值范例,就不成制止必要装箱、拆箱。请看上面的例子。
publicclassIntCollection:IList
{
...
privateArrayList_Ints=newArrayList();
publicintthis[intindex]
{get{return(int)_Ints[index];}}
publicintAdd(intitem)
{_Ints.Add(item);
return_Ints.Count-1;}
publicvoidRemove(intitem)
{_Ints.Remove(item);}
objectIList.this[intindex]
{get{return_Ints[index];}
set{_Ints[index]=(int)value;}}
intIList.Add(objectitem)
{returnAdd((int)item);}
voidIList.Remove(objectitem)
{Remove((int)item);}
...
}
staticvoidMain(string[]args)
{IntCollectionints=newIntCollection();
ints.Add(5);//装箱
inti=ints[0];//拆箱
}
大批装箱、拆箱对功能的影响不年夜,可是假如汇合的数据量十分年夜,对功能仍是有必定影响的。泛型可以制止对值范例的装箱、拆箱操纵,您能够经由过程剖析编译后的IL失掉印证。
staticvoidMain()
{
List<int>ints=newList<int>();
ints.Add(5);//不必装箱
inti=ints[0];//不必拆箱
}
泛型的完成
・泛型办法
staticvoidSwap<T>(refTa,refTb)
{Console.WriteLine("YousenttheSwap()methoda{0}",
typeof(T));
Ttemp;
temp=a;
a=b;
b=temp;
}
・泛型类、布局
publicclassPoint<T>
{
privateT_x;
privateT_y;
publicTX
{get{return_x;}
set{_x=value;}}
publicTY
{get{return_y;}
set{_y=value;}}
publicoverridestringToString()
{returnstring.Format("[{0},{1}]",_x,_y);}
}
泛型的Where
泛型的Where可以对范例参数作出限制。有以下几种体例。
・whereT:struct限定范例参数T必需承继自System.ValueType。
・whereT:class限定范例参数T必需是援用范例,也就是不克不及承继自System.ValueType。
・whereT:new()限定范例参数T必需有一个缺省的机关函数
・whereT:NameOfClass限定范例参数T必需承继自某个类或完成某个接口。
以上这些限制能够组合利用,好比:publicclassPoint<T>whereT:class,IComparable,new()
泛型的机制
・机制:
C#泛型代码在被编译为IL代码和有数据时,接纳特别的占位符来暗示泛型范例,并用专有的IL指令撑持泛型操纵。而真实的泛型实例化事情以"on-demand"的体例,产生在JIT编译时。
・编译机制:
1.第一轮编译时,编译器只为Stack<T>(栈算法)范例发生“泛型版”的IL代码与元数据-----其实不举行泛型范例的实例化,T在两头只充任占位符
2.JIT编译时,当JIT编译器第一次碰到Stack<int>时,将用int交换“泛型版”IL代码与元数据中的T---举行泛型范例的实例化。CLR为一切范例参数为“援用范例”的泛型范例发生统一份代码;但假如范例参数为“值范例”,对每个分歧的“值范例”,CLR将为其发生一份自力的代码。
泛型的一些成绩
・不撑持操纵符重载。我只晓得这么多了
范型的意义
泛型的意义安在?范例平安和削减装箱、拆箱并非泛型的意义,而是泛型带来的两个优点罢了(也许在.net泛型中,这是最分明的优点了)。泛型的意义在于――把范例作为参数,它完成了代码之间的很好的横向接洽,我们晓得承继为代码供应了一种从上往下的纵向接洽,但泛型供应了便利的横向接洽(从某种水平上说,它和AOP在头脑上有相通的地方)。在PersonCollection例子中,我们晓得Add()办法和Remove()办法的参数范例不异,但我们明白没法告知我们的程序这一点,泛型供应了一种机制,让程序晓得这些。事理固然复杂,但如许的机制也许能给我们的程序带来一些深远的变更吧。归根到底,Java跨平台可以,但是要重新编写代码,否则还分什么J2EE/J2SE/J2ME呢! |