当前位置:首页 > Windows程序 > 正文

第三章 C# 泛型

2021-03-27 Windows程序

当两个模块功能相似,仅仅只是类型不同的时候,你会怎么办呢。请看以下代码:

public class IntClass { List<int> Intlist = new List<int>(); public void AddList(int i) { Intlist.Add(i); } } public void Main() { IntClass c1 = new IntClass(); c1.AddList(1); c1.AddList(1); }

View Code

但是当我们想c1.AddList("hello word");要插入一个字符串类型的时候,你会怎么做呢?

二逼程序员会这样做:

public class StringClass { List<string> Intlist = new List<string>(); public void AddList(string i) { Intlist.Add(i); } }

View Code

普通程序员会这样做:

public class ObjClass { List<object> Intlist = new List<object>(); public void AddList(object i) { Intlist.Add(i); } }

View Code

仔细想想,不断装箱拆箱是否效率低下呢,当我们要插入bool,char,datetime.....等等类型的时候,我们需要copy这么多类吗?这时我们就用到了泛型。

1.泛型的声明:

public class Class1<T> { private List<T> List = new List<T>(); public List<T> GetList() { return List; } public void AddList(T t) { List.Add(t); } }

View Code

2.泛型的默认值:

T t=defalut(T); 如果T是值类型,则t=0;如果T是引用类型,则t=null.

3.泛型约束:

接口约束:where T:Interface   必须显示的实现接口

基类约束:where T:BaseClass 参数必须为BaseClass或者派生类

类约束:where T:class T必须是引用类型

值类型约束: where T:struct T必须是值类型

构造函数约束: where T:new()  必须有默认的构造函数

泛型类型约束: Where T:T1

4静态成员:

不同类型的泛型可以认为是不同的类。  所有静态成员只能在同类中共享。

public class mm<T> { public static string Name{get;set;} }

mm<int> a,mm<int> b,mm<sting>c       a,b可以共享Name,c不能

5.泛型类中的方法重载
方法的重载在.Net Framework中被大量应用,他要求重载具有不同的签名。在泛型类中,由于通用类型T在类编写时并不确定,所以在重载时有些注意事项,这些事项我们通过以下的例子说明:

public class Node<T, V>

{

public T add(T a, V b)          //第一个add

{

return a;

}

public T add(V a, T b)          //第二个add

{

return b;

}

public int add(int a, int b)    //第三个add

{

return a + b;

}

}

上面的类很明显,如果T和V都传入int的话,三个add方法将具有同样的签名,但这个类仍然能通过编译,是否会引起调用混淆将在这个类实例化和调用add方法时判断。请看下面调用代码:

Node<int, int> node = new Node<int, int>();

object x = node.add(2, 11);

这个Node的实例化引起了三个add具有同样的签名,但却能调用成功,,因为他优先匹配了第三个add。但如果删除了第三个add,上面的调用代码则无法编译通过,提示方法产生的混淆,因为运行时无法在第一个add和第二个add之间选择。

Node<string, int> node = new Node<string, int>();

object x = node.add(2, "11");

这两行调用代码可正确编译,因为传入的string和int,使三个add具有不同的签名,当然能找到唯一匹配的add方法。

由以上示例可知,C#的泛型是在实例的方法被调用时检查重载是否产生混淆,而不是在泛型类本身编译时检查。同时还得出一个重要原则:

当一般方法与泛型方法具有相同的签名时,会覆盖泛型方法。

泛型类的方法重写
方法重写(override)的主要问题是方法签名的识别规则,在这一点上他与方法重载一样,请参考泛型类的方法重载。

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/68757.html