C#泛型 泛型类扩展

来源:互联网 发布:apache web 压力测试 编辑:程序博客网 时间:2024/06/05 10:09
 泛型:更准确的使用一种以上的类型代码方式 泛型允许我们声明类型参数化的代码,我们可以用不同的类型进行实例化    也就是说,我们可以用“类型占位符”(类型参数)来声明,然后在创建实例时提供真实类型 **泛型不是类型,而是类型的模板** 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>  // 两个类型参数    //    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);            }        }    }
0 0
原创粉丝点击