c#----泛型(一)
来源:互联网 发布:在线网络理财产品排名 编辑:程序博客网 时间:2024/04/30 18:14
一、泛型
class Program { static void Main(string[] args) { Aint a = new Aint(2); Console.WriteLine(a.Num); Bstring b = new Bstring("a"); Console.WriteLine(b.Str); Console.Read(); } } public class Aint { private int num; public int Num { get { return num; } } public Aint(int i) { num = i; } } public class Bstring { private string str; public string Str { get { return str; } } public Bstring(string i) { str = i; } }
当两个模块的功能非常相似,却类型不同如果想要合并代码怎么办?
可以把类型改为object
public class Cobject { private object ob; public object Ob { get { return ob; } } public Cobject(object i) { ob = i; } }
虽然减少了代码量,但object不是类型安全的,而且会进行封箱拆箱。
所以泛型的作用:可以创建独立于被包含类型的类和方法。我们不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。
static void Main(string[] args) { Example<string> a = new Example<string>("a"); System.Console.WriteLine(a.Ex); Console.Read(); } public class Example<T> { private T ex; public T Ex { get { return ex; } } public Example(T i) { ex = i; } }
通用类型T只是一个占位符,在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。
所以可以认为:Example<string> a 和 Example<int> b是不同的类
他的优点显而易见:
1. 他是类型安全的。实例化了int类型的栈,就不能处理string类型的数据,其他数据类型也一样。
2. 无需装箱和折箱。这个类在实例化时,按照所传入的数据类型生成本地代码,本地代码数据类型已确定,所以无需装箱和拆箱。
二、默认值
public class Example<T> { public void Show(T str) { T a =default(T); if (str != null) a = str; } }
因为不知道是值类型,还是引用类型,所以不能给泛型赋值null或者0,要用default来设置,如果T是值类型则赋值null,反之0
三、泛型约束
现在有一个接口:
interface IName { string Name { get; set; } }
如果想让泛型类来显示名字(Name):可以将T转换为IName来显示,但是如果T类型没有实现接口IName就会异常,所以需要给T规定:必须实现IName接口
class Ducument<T> { public void Show(T doc) { Console.WriteLine(((IName)doc).Name); } }
则:
class Ducument<T> where T:IName
如此可以这样写:
class Ducument<T> where T:IName { public void Show(IName doc) { Console.WriteLine(doc.Name); } }
最后: People类如果没有实现IName接口就会提示错误
class Program { static void Main(string[] args) { People a = new People("VenVertu"); Ducument<People> p = new Ducument<People>(); p.Show(a); Console.Read(); } } interface IName { string Name { get; set; } } class People : IName { public string Name { get; set; } public People(string name) { this.Name = name; } } class Ducument<T> where T:IName { public void Show(IName doc) { Console.WriteLine("我叫 :"+doc.Name); } }
1.必须为值类型 T:class. 2.必须为引用类型 T:struct 3.必须有个无参构造函数 T:new()
继承一样可以有多个接口约束,只能有一个类约束,每个约束用逗号隔开。new()必须在最后一个。
四、泛型中的静态成员变量
class Program { static void Main(string[] args) { StaticDemo<int> a = new StaticDemo<int>(); StaticDemo<int> b = new StaticDemo<int>(); StaticDemo<string> str = new StaticDemo<string>(); Console.WriteLine(StaticDemo<int>.Count); Console.WriteLine(StaticDemo<string>.Count); Console.Read(); } } class StaticDemo<T> { public static int Count { get; set; } public StaticDemo() { Count++; } }
结果是 输出2 和 1 :所以StaticDemo<int>和StaticDemo<string>是两个不同的类型
=========在所有弱点中,最大弱点就是暴露弱点===========
- c#----泛型(一)
- Prefer C++(一)
- C要点(一)
- C基本概念(一)
- objective-c(一)
- 初涉C++(一)
- C基础(一)
- C语言(一)
- Unix C (一)
- C 语言(一)
- 练习题c++(一)
- c易错题(一)
- 初识C++(一)
- C-汇编(一)
- Linux+C(一)
- 嵌入式C(一)
- C++--开始(一)
- 《Effective C++》(一)
- js自定义对象
- Linux中文件隐藏属性chattr,lsattr
- 约瑟夫环
- 使用X-UA-Compatible来设置IE浏览器兼容模式
- handler 进行主线程与子线程之间的信息传递
- c#----泛型(一)
- maven指定依赖打成一个jar包
- struts2的result-type详解
- LINQ 的使用
- vmware workstation11下安装ubuntu14.04
- java汉字转拼音
- 【leetcode】Majority Element
- 第4周项目3-用对象数组操作长方体类
- js如何生成动态正则表达式?