C#泛型 泛型类扩展
2016-06-14 17:05
309 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013435119/article/details/51673160
泛型:更准确的使用一种以上的类型代码方式 泛型允许我们声明类型参数化的代码,我们可以用不同的类型进行实例化 也就是说,我们可以用“类型占位符”(类型参数)来声明,然后在创建实例时提供真实类型 **泛型不是类型,而是类型的模板** C#提供了5种泛型:类、结构、接口、委托和方法。前面四个是类型,方法是成员。
一、 泛型类:创建和使用常规的、非泛型的类的过程中有两个步骤:声明类并创建类的实例
泛型类不是实际的类,而是类的模板。必须先构建实际的类类型,然后创建这个构建后的类类型的实例
声明泛型类,构建真实的类类型,创建构建后的类类型的实例。
类型实参:替代类型参数的真实类型叫做类型实参
class Program { static void Main(string[] args) { // 泛型类 var stackInt = new MyStack<int>(); // 泛型类实例 var stackString = new MyStack<string>(); // 泛型类实例 stackInt.Push(3); stackInt.Push(5); stackInt.Push(7); stackString.Push("Generics ar great"); stackInt.Print(); stackString.Print(); // 泛型方法 var intArray = new int[] { 3, 5, 7, 9, 11 }; var stringArray = new string[] { "first", "second", "third" }; SimpleClass.ReverseAndPrint<int>(intArray); //调用泛型方法 SimpleClass.ReverseAndPrint(intArray); // 可以根据变量推断类型参数 简化写法 SimpleClass.ReverseAndPrint<string>(stringArray); // 泛型类扩展 var intSimple = new Simple<int>(3, 5, 7); var stringSimple = new Simple<string>("a1", "a2", "a3"); intSimple.Print(); // 调用执行 扩展类中的方法 stringSimple.Print(); Console.ReadKey(); } } class MyStack<T> // 泛型类 { T[] StackArray; // 一个参数类型的数组 int StackPointer = 0; int MaxStack = 10; bool IsStackFull { get { return StackPointer >= MaxStack; } } bool IsStackEmpty { get { return StackPointer <= 0; } } public void Push(T x) // 一个方法 传递 一个参数类型的形参 { if (!IsStackFull) { StackArray[StackPointer++] = x; // 压栈 } } public T Pop() // 出栈 { return (!IsStackEmpty) ? StackArray[--StackPointer] : StackArray[0]; } public MyStack() { StackArray = new T[MaxStack]; // 数组初始化后 } public void Print() // 遍历打印数组内容 { for (int i = StackPointer - 1; i >= 0; i--) { Console.WriteLine("value:{0}", StackArray[i]); } } }
二、 类型参数约束:提供额外信息让编译器知道参数可以接受那些类型的参数 ,这些额外的信息叫做约束
约束使用where 子句列出
每一个约束的类型参数有自己的where子句
如果形参有多个约束,它们在where子句中使用逗号分隔
where子句:在类型参数列表的关闭尖括号之后列出
在结尾不使用逗号或其他分隔符
可以以任何次序列出
where是上下文关键字,可以在其他上下文中使用
5中类型的约束和次序
类名:只有这个类型的类或从它继承的类才能用作类型实参
class : 任何引用类型,包括类、数组、委托和接口度可以用作实参
struct: 任何值类型都可以被用作类型实参
Interfacename:只有这个接口或实现这个接口的类型才能用作实参
new() :任何带有无参公共构造函数的类型都可以用作实参,这叫做构造函数约束
where中的约束必须有特定的顺序:最多只能有一个主约束,如果 有则必须放在第一位 可以有任意多的InterfaceName约束,如果存在构造函数约束,则必须放在最后
//class LinkedList<first,second> // 两个类型参数 3ff7 // where first:约束类型; 约束类型顺序:类名--class--struct--Interfacename--new() //{ //}
三、 泛型方法:泛型方法可以在泛型和非泛型类以及结构和接口中声明
声明泛型方法:在方法名参数列表后放可选的约束
在方法名称之后和方法参数列表之前放类型参数列表
class SimpleClass { public static void ReverseAndPrint<T>(T[] arr)// 在泛型类中声明泛型方法 { Array.Reverse(arr); // 反转数组 foreach (T item in arr) { Console.WriteLine(item); } } }
四、 扩展方法和泛型类
这里简单描述下非泛型类的扩展:
1、声明扩展方法的类必须声明为static
2、扩展方法本身必须声明为是static
3、扩展方法必须包含关键字this作为它的第一个参数类型,并且在后面跟着它所扩展的类的名称
泛型方法的扩展和方法扩展一样
class Simple<T> { T[] arr = new T[3]; public Simple(T s1, T s2, T s3) //构造函数 { arr[0] = s1; arr[1] = s2; arr[2] = s3; Array.Reverse(arr); // 反转数组 } public T[] Ergodic() // 遍历打印 { return arr; } } static class ExtendSimple // 泛型类的扩展 静态声明类 { public static void Print<T>(this Simple<T> se) // 泛型类扩展 方法 { T[] arr = se.Ergodic(); foreach(T item in arr) { Console.WriteLine(item); } } }
相关文章推荐
- C#泛型 C#泛型类与结构
- [置顶] C#泛型入门学习泛型类、泛型集合、泛型方法、泛型约束、泛型委托
- C#泛型-泛型类
- C#泛型(三)——泛型类的功能
- 黑马程序员——泛型类来完成功能扩展
- 译:泛型类的标记扩展
- 黑马程序员_泛型类来完成功能扩展
- 泛型类和扩展方法
- 关于泛型类和扩展方法的一点思考
- C#泛型(二)——创建泛型类
- C#泛型(二)——创建泛型类
- CentOS yum php mcrypt 扩展安装
- ASP网站怎么都配不好原来是要web扩展里面把active server pages点允许才行.
- 设计一个可扩展的用户登录系统
- ARCH linux virtualbox 使用USB等扩展功能
- linux--安装phpcurl扩展
- Hashpump实现哈希长度扩展攻击
- Hadoop的C++扩展了解(3)
- 不重新编译php, 扩展gd库
- FTP协议的分析和扩展