当前位置:编程学习 > C#/ASP.NET >>

用人类自然的语言说泛型,保证一听既懂,一懂就会啦

泛型
一、什么是泛型?
通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率

二、实例化泛型
1、可以使用任何类型来声明和实例化
2、申明和实例话都必须用一个特定的类型来代替一般类型T
3、例子:
//原来写法
Public class Stack
{
object[] m_Items;
public void Push(object item)
{...}
public object Pop()
{...}
}
Stack stack = new Stack();
stack.Push(1);
int number = (int)stack.Pop();

//有了泛型后
Public class Stack<T>
{
T[] m_Items;
public void Push(T item)
{...}
public T Pop()
{...}
}
Stack<int> stack = new Stack<int>();
stack.Push(1);
int number = (int)stack.Pop();

三:泛型的好处
1、一次性的开发、测试和部署代码,通过任何类型来重用它
2、编译器支持和类型安全
3、不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。
注:值类型大概可以提高200%,引用类型大概为100%

四:多个泛型
1、单个类型可以定义多个泛型

五:泛型别名
1、在文件头部使用using 为特定类型取别名,别名作用范围是整个文件
2、例子
using List = LinkedList<int,string>;
class ListClient
{
static void Main(string[] args)
{
List list = new List();
list.AddHead(123,"AAA");
}
}

五:泛型约束
(1)、派生约束
如:
public class LinkedList<K,T> where K:IComparable
{
T Find(K key)
{
if (str.Key.CompareTo(key) == 0)//只有实现这个接口才可比较
}
}

注意:
1、所有的派生约束必须放在类的实际派生列表之后
如:public class LinkedList<K,T>:IEnumerable<T> where K:IComparable<K>
    {...}
2、一个泛型参数上可以约束多个接口(用逗号分隔)
public class LinkedList<K,T> where K:IComparable<K>,IConvertible
3、在一个约束中最多只能使用一个基类
4、约束的基类不能是密封类或静态类
5、不能将System.Delegate或System.Array约束为基类
6、可以同时约束一个基类以及一个或多个接口,但是该基类必须首先出现在派生约束列表中。
7、C#允许你将另一个泛型参数指定为约束
public class MyClass<T,U> where T:U
{...}
8、可以自己定义基类或接口进行泛型约束
9、自定义的接口或基类必须与泛型具有一致的可见性

(2)、构造函数约束
如:
class Node <K,T> where T:new()
{
}
注意:
1、可以将构造函数的约束和派生约束结合起来,前提是构造函数的约束出现在约束列表中的最后

(3)、引用/值类型约束
1、可以使用struct约束将泛型参数约束为值类型(如int、bool、enum),或任何自定义结构
2、同样可以使用class约束将泛型参数约束为引用类型
3、不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类
4、不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类
5、虽然您可以使用类和默认构造函数约束,但是这样做没有任何价值
6、可以将引用/值类型约束与接口约束组合起来,前提是引用/值类型约束出现在约束列表的开头

六:泛型和强制类型转换
1、C#编译器只允许将泛型参数隐式转换到Object或约束指定的类型
如:
interface IS{...}
class BaseClass{...}
class MyClass<T> where T:BaseClass,IS
{
void SomeMethod(T t)
{
IS obj1 = t;
BaseClass obj2 = t;
object obj3 = t;
}
}
2、编译器允许你将泛型参数显示强制转换到其他任何借口,但不能将其转换到类
interface IS{...}
class SomeClass{...}
class MyClass <T> //没有约束
{
void SomeMethod(T t)
{
IS obj1 = (IS)t; //可以
SomeClass obj2 = (SomeClass)t //不可以
}
}
3、可以使用临时的Object变量,将泛型参数强制转换到其他任何类型
class SomeClass{...}
class MyClass <T> 
{
void SomeMethod(T t)
{
object temp = t;
SomeClass obj = (SomeClass)temp;//可以
}
}
注意:这里只是告诉你这样写是可以的,但是要不要这样写?不要这样写,因为如果t确实没有继承SomeClass编译没错但是运行就会出错
4、解决上面强制转换问题,可以使用is和as运算符进行判断
public class MyClass<T>
{
public void SomeMethod<T t>
{
if (t is int ){...}
if (t is LinkedList<int,string>){...}
//如果泛型参数的类型是所查询的类型,则is运算符返回true
string str = t as string;
//如果这写类型兼容,则as将执行强制类型转换,否则将返回null
if (str != null){...}
LinkedList<int,string> list = t as  LinkedList<int,string>;
if (list != null){...}
}
}

七:继承和泛型
1、在从泛型基类派生,可以提供类型实参,而不是基类泛型参数
public class BaseClass<T>{...}
public class SubClass:BaseClass<int>
2、如果子类是泛型,而非具体的类型实参,则可以使用子类泛型参数作为泛型基类的指定类型
public class BaseClass<TT>{...}
public class SubClass<T>:BaseClass<T>{...}
3、在使用子类泛型参数时,必须在子类级别重复在基类级别规定的任何约束
4、基类可以定义其签名使用泛型参数的虚礼方法,在重写它们时,子类必须在方法签名中提供相应的类型。
如:
public class BaseClass<T>
{
public virtual T SomeMethod()
{...}
}
public class SubClass:BaseClass<int>
{
public override int SomeMethod()
{...}
}
5、如果该子类是泛型,则它还可以在重写时使用它自己的泛型参数
public class SubClass<T>:BaseClass<T>
{
public override T SomeMethod()
{...}
}
6、你可以定义泛型接口、泛型抽象类,甚至泛型抽象方法。
7、不能对泛型参数使用+或+=之类的运算符
public class Calculator<T>
{
public T Add (T arg1,T arg2)
{
return arg1 + arg2;//错误
}
}
但是我们可以通过泛型抽象类、接口来实现在个功能,因为实现泛型抽象类、接口我们就已经明确传一个参数了,就可以执行诸如+这样的操作。

八:泛型方法
1、方法可以定义特定于其执行范围的泛型参数
public class MyClass<T>
{
public void MyMethod<X>(X x)
{...}
}
2、即使各包含类根本不使用泛型,你也可以定义方法特定的泛型参数
public class MyClass
{
public void MyMethod<T>(T t)
{...}
}
注意:该功能只使用于方法,属性,索引器只能使用在类的作用范围中定义的泛型参数。
3、调用泛型方法
MyClass obj = new MyClass();
obj.MyMethod<int>(3);
也可以这样:
MyClass obj = new MyClass();
obj.MyMethod(3); //该功能称为泛型推理
4、泛型方法也可以有自己的泛型参数约束
pubic class MyClass
{
public void SomeMethod<T>(T t) where T:IComparable<T>
{...}
}
5、子类方法实现不能重复在父级别出现的约束
public class BaseClass
{
public virtual void SomeMethod<T>(T t)where T:new()
{...}
}
pubic class SubClass:BaseClass
{
public override void SomeMethod<T>(T t)//不能再有约束
{...}
}
6、静态方法
静态方法可以定义特定的泛型参数和约束
public class MyClass<T>
{
public static T SomeMethod<X>(T t,X x)
{...}
}
int number = MyClass<int>.SomeMethod<string>(3,"AAA");
或者:int mumber = MyClass<int>.SomeMethod(3,"AAA");

九:泛型委托
1、在某个类中定义的委托可以利用该类的泛型参数
2、委托也可以定义自己的泛型参数 --------------------编程问答-------------------- 沙发^_^

真是我为人人,人人为我啊,thanks LZ --------------------编程问答-------------------- 不客气,哈哈 --------------------编程问答-------------------- ? --------------------编程问答-------------------- ?
--------------
? --------------------编程问答-------------------- up --------------------编程问答-------------------- 标一下 --------------------编程问答--------------------


消习了.^_^




--------------------编程问答-------------------- 作個記號先。 --------------------编程问答-------------------- 标一下
--------------------编程问答-------------------- 谢谢. 还是迷糊 --------------------编程问答-------------------- ............ --------------------编程问答-------------------- up --------------------编程问答-------------------- up
--------------------编程问答-------------------- 路过 --------------------编程问答-------------------- 楼主是个有心人啊。。 --------------------编程问答-------------------- up --------------------编程问答-------------------- mark --------------------编程问答-------------------- d --------------------编程问答-------------------- up --------------------编程问答-------------------- up --------------------编程问答-------------------- 收藏了 --------------------编程问答-------------------- 留个记号 --------------------编程问答-------------------- mark --------------------编程问答-------------------- mark too --------------------编程问答-------------------- 泛型不是包治百病的灵丹妙药,OO也不是。 --------------------编程问答-------------------- j --------------------编程问答-------------------- mark
--------------------编程问答-------------------- 学习一下.... --------------------编程问答-------------------- up --------------------编程问答-------------------- hao --------------------编程问答-------------------- up --------------------编程问答-------------------- 学习 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 学习中... --------------------编程问答-------------------- 还很迷糊,跟那个,每个主妇都是一个ERP主管的那篇没得比呀

不过还是感谢楼主,我水平不行不是楼主写得不好。 --------------------编程问答-------------------- 标一下 --------------------编程问答-------------------- Hot heart Lz --------------------编程问答-------------------- up --------------------编程问答-------------------- 学习一下 --------------------编程问答-------------------- Mark! --------------------编程问答-------------------- 感谢楼主分享~ --------------------编程问答-------------------- mark --------------------编程问答-------------------- 还是简单了点,不过还是感谢,正准备项目中使用 --------------------编程问答-------------------- 感谢楼主分享...唯一遗憾是...这是人类官方语言... --------------------编程问答-------------------- 标记 --------------------编程问答-------------------- 收藏了 --------------------编程问答-------------------- 写上这几个字不接分也值 --------------------编程问答--------------------
引用楼主 MicrosoftMessage 的帖子:
四:多个泛型 
1、单个类型可以定义多个泛型 


这句话有语病。

泛型是类型的函数,它的结果也还是类型。

例如数学函数 f(x),x是整数,函数也返回整数,你不能说“整数定义多个f函数”这样反而会搞糊涂。f函数只有一个,f的结果才有多个,因为它是函数而不是常数嘛。

嗯,用打比方的方式将概念可以一听既懂,但是如果真的实际说概念的时候也要谨慎地不要产生歧义呀,不要因为打了比方说过了就放松对概念叙述的准确性要求。 --------------------编程问答-------------------- mark,up --------------------编程问答-------------------- 学习 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 留个记号
--------------------编程问答-------------------- mark --------------------编程问答-------------------- 先留着,慢慢看 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 好贴. --------------------编程问答-------------------- Thanks. --------------------编程问答-------------------- Thanks. --------------------编程问答-------------------- 收 --------------------编程问答-------------------- 做标记 --------------------编程问答-------------------- 收藏学习 --------------------编程问答-------------------- http://www.qidian.com/BookReader/1049449,21336092.aspxhttp://www.qidian.com/BookReader/1049449,21336092.aspxhttp://www.qidian.com/BookReader/1049449,21336092.aspx --------------------编程问答-------------------- 飘过 --------------------编程问答-------------------- 顶一个 --------------------编程问答-------------------- 学习了,谢谢分享` --------------------编程问答-------------------- 谢谢分享! --------------------编程问答-------------------- mark --------------------编程问答-------------------- jf --------------------编程问答-------------------- mark --------------------编程问答-------------------- 泛型就是类型动态化 --------------------编程问答-------------------- 辛苦楼主
--------------------编程问答-------------------- 学习中... --------------------编程问答-------------------- mark --------------------编程问答--------------------
引用 70 楼 cfreez 的回复:
泛型就是类型动态化

这个比较清楚 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 正要学习 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 有点意思!! --------------------编程问答-------------------- 不懂。依旧。 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 不错,还是迷糊 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 路过的,进来好生学习学习的! --------------------编程问答-------------------- mark
--------------------编程问答-------------------- mark --------------------编程问答-------------------- 搂搂 --------------------编程问答-------------------- up --------------------编程问答-------------------- 溜过!看了!谢谢!收了!辛苦 --------------------编程问答-------------------- MARK --------------------编程问答-------------------- 标记 --------------------编程问答-------------------- 這多人了啊。 --------------------编程问答-------------------- 好帖加精............. --------------------编程问答-------------------- mark
--------------------编程问答-------------------- gghd 正学这个呢。 --------------------编程问答-------------------- mark --------------------编程问答-------------------- 学习了 --------------------编程问答-------------------- 学习!!! --------------------编程问答-------------------- 支持LZ --------------------编程问答-------------------- 男士皮具——韦尚电子商务有限公司:www.vishang.com --------------------编程问答-------------------- 不是人类 ~
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,