说来也惭愧,之前不知道是为什么没人指点还是怎么着~!都还没用过泛型~今天学好了,明天去消灭沉余代码~!

本文将为大家讲述。NET中最常见的一种特性,C#泛型。希望通过本文能帮助大家更好的学习和理解C#泛型,在平时的开发工作中起到事半功倍的效果。
  
  泛型,.NET的这个特性相信大家都已经很熟悉了,提起泛型,不能不首先提到C++中的模板,C++中模板的引入大大提高了代码的重用性,因此也得到了许多程序员的喜爱。因此,在同为强类型语言平台的。NET
2.0和Java 1.5中,它们也都不约而同的引入了泛型的对语言和平台的支持。不过虽然三种语言最终都提供了将类型参数化的功能,然而这个功能在三个平台或语言中的实现却大大不同。相对来说,C++的模板功能是三者中最为强大的,不过由于。Net和Java对类型安全和稳定性要求更高,它们对泛型的支持要稍微简单,不过即使如此,二者对泛型特性的实现也引起了两个阵营中程序员们的争论,不过最终普遍认为Java的伪泛型(擦拭法)要比。NET的JIT级别的真正的泛型性能要差(java仍然有装箱,拆箱操作)。当然这些是后话,下面我们来看看。NET的泛型到底如何使用吧!
  
  基本介绍
  
  .NET
2.0以后以后支持在很多类型上使用泛型,包括类、结构、接口、委托和方法成员,在这些类型上使用泛型和在类上使用是一样的。它甚至支持同一个接口但不同泛型类型的实现,这有点类似重载在类级别的实现。最后。NET允许你同时定义多个泛型类型。
  
  在泛型方法中的泛型类型基本跟在类中使用情况一样,不过泛型方法有一个方便程序员的地方就是它的类型推断功能,这意味着程序员可以即能和使用普通方法一样使用这些方法,同时又能享受泛型带来的方便。e.g.
  
  代码
  
  static
void Test<T, U>(T t, U u)
  
  { }static
void
main(){
  
  //在函数中我们可以不用声明参数类型,编译器会自动根据实际数据
  
  //自动推断类型 
Test(10, “20”);Test(1.1,
2.2);
  
  }
  
  下面我们来看看泛型在。NET中使用的一些需要注意的地方。
  
  1.
泛型在嵌套类中的使用。嵌套的子类会自动继承(?)包裹类的泛型类型,当然,你也可以在嵌套类中覆盖掉包裹类的类型,不过编译器会在编译的时候发出警告来提醒用户注意避免误写。e.g.
  
  class
Container<T,
U>{
  
  //编译器会在这里发出警告
  
  //告诉用户这里的泛型和包裹类相同
  
  class
Nested<U>{ void Method(T p0, U p1)
  
  {
}}}
  
  2.
协变和逆变的问题。关于协变和逆变的定义简单来说就是泛型类型是否允许子类和父类之间转换,这里不做详细讨论,读者如果有兴趣可以参考这篇文章。在。net
4.0以前是不支持协变和逆变的,这也让我们的代码有些时候实现起来很别扭。下面可以看个简单的例子(注:这个例子仅作说明用,不一定恰当)。
  
  首先我们定义两个数据类型,IData和IOperation:
  
  interface
IData{void method();}
  
  interface
IOperation<T>
  
  where T : IData{ void
Run(T
data);}
  
  然后我们分别定义不同类型的数据和操作类:
  
  代码
  
  class
AddData : IData{public int A1, A2;
  
  public
void method()
  
  { }}class Add :
IOperation<AddData>
  
  {public void
Run(AddData d)
  
  {Console.WriteLine(d.A1 +
d.A2);}}
  
  class ComplexData : IData{public
void method()
  
  {
}
  
  public int A1, A2, B1,
B2;}
  
  class ComplexAdd :
IOperation<ComplexData>{
  
  public void
Run(ComplexData
d)
  
  {Console.WriteLine(“{0}+{1} 
i”,d.A1 +
d.A2,d.B1+d.B2);
  
  }}
  
  这里如果能这样使用我们认为应该是安全的:
  
  IOperation<IData>
opr = new
Add();
  
  opr.Run(data1);
  
  opr
= new
ComplexAdd();
  
  opr.Run(data2);
  
  然而这样的代码是无法通过编译的,尽管我们知道它们的使用绝对安全的,因为AddData或ComplexData是IData的子类。幸运的是,在。Net4.0中程序员将不会有这个烦恼了。
  
  3.
泛型不支持操作符。在C++中模板支持操作符,然而,由于操作符是静态的并且是编译时决定的(参看这篇文章),因此作为运行时的泛型无法实现类型间的该项操作,虽然你可以通过接口来达到同样功能,但方便的操作符终究无法在泛型中得到支持。这可以算是C#泛型的一个缺点,因为在很多时候它确实很有用。
  
  4.
泛型的类型转换问题。泛型无法从其他类型(object除外)直接强制转换,这个时候如果需要将其他类型转换为泛型对象时有两种方式,一种是该泛型约束是class或基类,这时候可以通过as
操作符来转换,如 return somevalue as
T.但是有时候如果我们不知道该泛型的类型或者该泛型类型是struct该如何转换呢?答案是通过两次类型转换,首先我们把待转换对象转换为object对象,然后直接对该object对象强制转换为T,e.g.
return
(T)(object)someVar.具体例子你可以参考这篇文章。
  
  最后,在泛型中有个关键字--default,顾名思义,它是在引用类型和值类型没有初始化的时候提供默认值的。对引用类型默认值是null,值类型则是0.
  
  泛型约束
  
  如果。Net仅仅出现泛型而没有泛型约束,我想泛型的功能一定会大打折扣的,正是有了泛型约束,才让我们在操作这些类型更加规范和准确。这也是同为强类型的C#比C++的模板更安全的一点。
  
  和类声明继承关系时一样,泛型约束可以声明多个接口和最多一个基类约束,并且如果声明了基类约束,类约束必须放在约束条件的首位,这和我们声明类的继承关系要求一样。另外,声明约束的类不能是密封类或某些特殊的结构(如Nullable<T>),如我们不能声明约束类为string或System.Nullable<T>.最后,与我们在类声明多个接口继承关系一样,泛型的约束间是AND而非OR关系,也就是说,如果你添加了多个约束,那么泛型使用必须满足所有的约束条件。
  
  我们可以通过关键字class和struct来限定类型是值类型还是引用类型,不过由于基类约束已经表明了泛型类型是类还是结构,所以我们不能同时将class或struct约束和基类(结构)约束一起使用,e.g.class
ClassA<T>where T:BaseClass,class
是不允许的。另外一个需要注意的就是class和struct约束也必须在其他任何约束条件之前。
  
  另外一个值得注意的约束关键字是new(),
new
关键字意味着泛型对象必须提供一个无参构造函数,需要注意的是,new()约束必须放在所有约束的最后面。这个约束有时会有用,不过有时看起来更像鸡肋。首先,new()约束虽然表明你可以在类中对泛型对象使用new()操作符实例化对象,然而在CIL对该对象的实例化仍然是通过反射来实现的,即T
a=new T()相当于T a = System. Activator.
CreateInstance<T>();这样程序效率会有所降低。另一方面,目前new约束仅仅支持无参构造函数的约束,而无法支持用户自定义参数的构造函数约束,虽然用户可以自己通过工厂方法来传递参数,但终究不够自由,这让new()约束有时没太大用武之地。
  
  约束不支持委托和枚举类型,例如,你不能这样定义:class
ClassA<T> where T:Delegate.
这是由于委托和枚举被认为是特殊的类,它无法被指定为类型参数。编译器无法根据Delegate来完成编译器的类型检查。
  
  最后类型约束支持继承,但同时你必须在子类定义泛型的时候再重新声明一遍父类的所有约束。设计者的出发点是让程序员能清楚子类中约束从何而来,减少疑惑。但从另外个角度来讲,这样反而会让程序员不得不多添加一些重复的代码,即使你已经知道它的约束条件都有哪些。
  
  泛型内部实现
  
  泛型在。NET中真正做到了平台级别的支持,在C#中,泛型同样是对象。事实上,编译器会在编译的时候将泛型参数转换为特殊的元数据,CLR会根据需要生成其实际的类型。为避免装箱和拆箱,值类型的泛型实现和引用类型的是不一样的。下面我们来具体看看它们有和不同。
  
  1.
值类型的泛型对象实例化
  
  第一次用值类型作为参数来构造泛型类型时,运行库会创建专用泛型类型,将提供的参数代入到
MSIL 中的适合位置。对于每个用作参数的唯一值类型,都会创建一次专用C#
泛型类型。这种特定类型的泛型类其实就相当于包含特定值类型的本地代码,它将对性能提升很有帮助。
  
  2.
引用类型的泛型对象实例化
  
  对于引用类型,泛型的工作方式略有不同。第一次使用任何引用类型构造泛型类型时,运行库会创建专用泛型类型。用对象引用(或者说指针更好)替换MSIL中的参数。然后,每次使用对象的引用作为参数来实例化。构造类型时,无论引用类型的详细类型是什么,运行库都会重用以前创建的泛型类型的专用版本。之所以可以这样,
是因为所有对象引用的大小相同
.
  
  总结
  
  在。NET类库中处处都可以看到泛型的身影,尤其是数组和集合中,泛型的存在也大大提高了程序员的开发效率。更重要的是,C#的泛型比C++的模板使用更加安全,并且通过避免装箱和拆箱操作来达到性能提升的目的。因此,我们很有必要掌握并善用这个强大的语言特性。

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

//学习测试泛型

public
ActionResult T_Test()

{

    var
linq = T_A(DB.Bus_User.OrderBy(a => a.UserId).Skip(0).Take(20))[0];

    return
View(linq);

}

public
ActionResult T_Test1()

{

    var
linq = T_A(DB.TestTime.OrderBy(a => a.id).Skip(0).Take(20))[0];

    return
View(linq);

}

public
List<T> T_A<T>(T li)

{

    List<T> model = new
List<T>();

    model.Add(li);

    return
model;

}

  

时间: 2024-11-03 03:38:59

说来也惭愧,之前不知道是为什么没人指点还是怎么着~!都还没用过泛型~今天学好了,明天去消灭沉余代码~!的相关文章

不知道你们遇到没遇到这种情况,谈谈ng-if/ng-repeat产生子作用域,ng-model取不到相应的值

不知道你们遇到没遇到这种情况,谈谈ng-if/ng-repeat产生子作用域,ng-model取不到相应的值,这个问题是怎么产生的呢?,因为他们都各级产生了一个子作用域. ng-repeat demo ng-repeat经常是用来解析一个数组,将值赋值到一个list中 具体的$parent主要应用在重名的情况下 <!DOCTYPE html> <html lang="en" ng-app="myapp"> <head> <m

反正也没人看

反正也没人会看,也没技术含量内容,随便乱写写. 嘛,清明难得能放个假,对我这种特殊工种.不知毕业多少年,又看起了MIT python语言和计算机导论和深入理解计算机系统.都是正文看得挺快,一到习题就瞎火,CSAPP这种在第二章讲无符号数和补码的转换的,由我若鸡一般的水平还是能勉强一天看上4-5页的,今天看到累也就看了5页,这还是简单的内容部分,真是对自己能力水平感到无语了. 看看MIT 6.001X感觉还行,之前的problem set 3 做完了后恨不得直接写篇日志啊 庆祝啊,贴上代码啊,装个

支付婊事件中, 微软应该背负责任吗?为什么没人指责微软?

匿名用户 钱一昶.孙哲浩.ImagineBreak 等人赞同 真的是微软的责任?WP的API再怎么不开放,也不至于让软件登录界面没法做出注册和找回密码吧?不至于让软件没法扫二维码吧? 发布于 昨天 14:28 1 条评论 赞同32 反对,不会显示你的姓名 可可苏玛,专业争当1% 路生.赤炎血.丞之 等人赞同 微软已经尽力在跟阿里谈判了,阿里还是微软在国内最高等级的[合作伙伴]之一,最高等级哦最高等级哦没有更高了哦:不但谈判甚至还[出资],都做到这份上了还要微软怎么办,收购小米收购魅族收购华为然后

人生,别认输,因为没人希望你赢

别认输,因为没人希望你赢:别靠人,因为只有自己最可靠:别乞求,因为别人等着看笑话: 别落魄,因为一堆人在等着落井下石:别回首,因为看到的是未修复的裂痕:别离愁,因为只会才下眉头却上心头: 别低头,因为地上没有黄金只有石头:别强求,因为硬摘的果实,没有甜头.有些事情不要太计较,睁一只眼,闭一只眼,就会过去的. 别哭穷,因为没人会给你钱:别喊累,因为没人会帮你做:别想哭,因为大家并不在乎: 最难打开的是心门,最难走的路是心路,最难过的桥是心桥,最难调整的是心态.世界上最难干的工程是改造人的内心世界.

如果你建造了一个精良的模型却没人用,你肯定不会得到赞誉(转)

注:本文编译自 How to do Data Science ,作者 Brandon Rohrer 为微软高级数据科学家. <哈佛商业评论>曾宣称“数据科学家”是二十一世纪最性感的职业.所谓性感,既代表着难以名状的诱惑,又说明了大家对它又不甚了解. 如何做好数据科学呢? 微软高级数据科学家 Brandon Rohrer 概括了做数据科学的七大步骤,手把手教你做数据科学. 1. 获取更多的数据 数据科学的原材料是数字和名称的集合,测量.价格.日期.时间.产品.标题.行动等,数据科学无所不包.你也

家里没人怎么防火防盗?装上这段自动看家程序

假期马上就要到了,不少朋友即将出门旅游或探亲访友.即使没有强迫症的你,也许在锁门离开的一瞬间,心里也会泛起一丝淡淡的担忧:离开家这么长时间,如何才能确保家里一切安好? 长时间家里没人,最主要的威胁来自两个:一个是小偷,另一个是火灾.防盗防火防闺蜜虽然是永恒的主题,但所有措施都是在出门以前做的,究竟效果如何? 最好是能有一个装备,在主人不在家时实时监控家里.一旦有问题,迅速通知主人,同时报警. 1.监控系统 1.1市面上的监控系统 针对这个问题,网上有不少现成的监控系统.原理大概是:通过探测器监测

保利尼奥离中超如肖申克救赎 没人再说人傻钱多

保利尼奥离中超如肖申克救赎 没人再说人傻钱多 新浪综合 | 2017-08-15 00:16 文章来源:明说 今夜,"暴力鸟"终于还是飞走了. 我第一时间想到的,是电影肖申克救赎里,Redd在谈到Andy的越狱时,稍稍带有些不甘,又衷心为Andy高兴的一句话: "Some birds are not meant to be caged, their feathers are just too bright." 有些鸟是无法关在笼子里的,它的每一片羽毛都闪耀着自由的光

以前一张执照100万,现在1万没人要

这个行业曾经被认为闭着眼睛都能赚钱,在2000年左右迎来了发展的黄金期,但现在却逐渐走向没落,不得不直面艰难转型之路.万千网吧主.网咖主如案板上的鱼,正经历时代变迁之刃. 一 "原来还指望这网吧转让费能多赚点利润的,现在网吧的日子越来越不好过了." 卢女士忧虑地说. 2014年,俗称"网吧新规"的"促进互联网上网服务行业健康有序发展"相关通知发布,成为网吧行业发展的分水岭.这标志着网吧审批的准入许可等方面门槛降低,以往一张网吧审批执照"

10条没人告诉你的创意秘诀

艺术家 Austin Kleon 的著书<像艺术家一样去偷:10条没人告诉过你的创意要诀>篇幅不长,却给初出茅庐的艺术家们(有创意的那类)提供了许多有益的指导. 1. 像艺术家一样去偷 青涩的诗人会模仿:成熟的诗人会偷:蹩脚的诗人只会糟蹋拿来的东西有才的诗人则把它们改得更好,或者至少能有所创变. Austin 认为,创意的作品总是建立在先例的基础上,因此没有什么是绝对原创的.他建议我们把世界上所有的东西都看成值得偷和不值得偷的两种.要偷那些能让你(或者是你的事业)出类拔萃的东西.作者还补充说,