e心e意

导航

C#泛型的接口、类、结构、方法、委托等

1.使用泛型的栈的示例

namespace 泛型的栈的示例
{
    /*学习步骤:
     什么是栈?
     * int类型的栈
     class MyIntStack
     {
     * int StackPointer=0;
     * int[]stackArray;——申明int类型的栈
     * public void Push(int x);——输入类型int
     * {
     * .............
     * }
     * public int Pop()——返回类型为int
     * {
     * 
     * }
     * }
     * float类型的栈
     class MyFloatStack
     {
     * int StackPointer=0;
     * float []stackArray;——申明int类型的栈
     * public void Push(float x);——输入类型float
     * {
     * .............
     * }
     * public float  Pop()——返回类型为float
     * {
     * ........................................
     * }
     * }
     * 声明一个T符号类型的栈,这里的T是一个泛指概念
     * class MyStack<T>
     {
     * int StackPointer=0;
     * T []stackArray;——申明T类型的栈
     * public void Push(T x);——输入类型T
     * {
     * .............
     * }
     * public T  Pop()——返回类型为T
     * {
     * ........................................
     * }
     * }
     * 声明泛型类
     * 声明一个简单的泛型类和声明普通类差不多,区别:
     * 在类名之后放置一组尖括号。
     * 在括号中用逗号分割的占位符字符串来表示
     * 希望提供的类型,也叫做类型参数
     * 在泛型类声明的主体使用类型参数来表示
     * 应该被替代的类型。例子:
     * class SomeClass<T1,T2>
     * {
     * public T1 SomeVar=new T1();
     * public T2 OtherVar=new T2();
     * }
     */
    class MyStack<T>//声明泛型类
    {
        T[] StackArray;
        int StackPointer = 0;
        public void Push(T x)
        {
            if (!IsStackFull)
                StackArray[StackPointer++] = x;
        }
        public T Pop()//定义有返回值方法
        {
            return (!IsStackEmpty)//条件运算符,可以用if...else...语句等价表示。
                ? StackArray[--StackPointer]
                : StackArray[0];
        }
        const int MaxStack = 10;
        bool IsStackFull//声明属性
        {
            get
            {
                return StackPointer >= MaxStack;
            }
        }
        bool IsStackEmpty//声明属性
        {
            get
            {
                return StackPointer <= 0;
            }
        }
        public MyStack()
        {
            StackArray = new T[MaxStack];
        }
        public void Print()
        {
            for (int i = StackPointer - 1; i >= 0; i--)
                Console.WriteLine("Value:{0}",StackArray [i]);
        }
    }
    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);
            StackInt.Print();
            StackString.Push("Generics are great!");
            StackString.Push("Hi there!");
            StackString.Print();
        }
    }
}

2.泛型方法

namespace 泛型方法示例
{
    /*
     什么是where子句:
     * where子句约束必须有特定的顺序:
     * 最多只能有一个主约束,如果有则必须放在第一位
     * 可以有任意多的InterfaceName约束;
     * 如果存在构造函数,则必须放在最后;
     * 什么是泛型方法,怎样声明?
     * 与其他泛型不一样,方法是成员,不是类型。
     * 泛型方法 可以在泛型和非泛型类以及结构和接口中声明。
     * 声明泛型方法:
     * 泛型方法和其他泛型一样,有类型参数列表和可选的约束。
     * 泛型方法有两个参数列表;
     * 封闭的圆括号内的方法参数列表;
     * 封闭在尖括号内的类型参数列表;
     * public void PrintData<S,T>(Sp,Tt)where S:Person声明泛型方法
     * {
     *........................
     * }
     */
    class Simple
    {
        static public void ReverseAndPrint<T>(T[] arr)//声明泛型方法
        {
            Array.Reverse(arr);
            foreach (T item in arr)//使用类型参
                Console.WriteLine("{0}",item .ToString ());
            Console.WriteLine("");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var intArray = new int[] { 3,5,7,9,11};
            var stringArray = new string[] { "first","second","third"};
            var doubleArray = new double[] { 3.567,7.891,2.345};
            Simple .ReverseAndPrint <int>(intArray );//调用方法
            Simple .ReverseAndPrint (intArray );//引用类型并调用
            Simple .ReverseAndPrint <string>(stringArray );
            Simple.ReverseAndPrint(stringArray );
            Simple .ReverseAndPrint <double >(doubleArray );
            Simple.ReverseAndPrint(doubleArray );
        }
    }
}

3.扩展方法和泛型类

namespace 扩展方法与泛型类
{
    /*泛型类的扩展方法有以下特点:
     必须声明为static;
     必须是静态类成员;
     第一个参数类型中必须有关键字this,
     后面是扩展的泛型类的名字;*/
    static class ExtendHolder//扩展方法
    {
        public static void Print<T>(this Holder<T>  h)
        //声明扩展方法并关联到泛型类Holder<T>上。
        {
            T[] vals = h.GetValues();
            //调用泛型类的方法。
            Console.WriteLine("{0},\t{1},\t{2}",vals[0],vals [1],vals [2]);
        }
    }
    class Holder<T>
    //声明泛型类
    {
        T[] Vals = new T[3];
        //声明并初始化数组。
        public Holder(T v0,T v1,T v2)
        //构造函数,为数组赋值。
    {
    Vals [0]=v0;Vals[1]=v1;Vals[2]=v2;
    }
    public T[]GetValues()
        //声明方法,返回数组类型。
{
return Vals;
}
    }
    class Program
    {
        static void Main(string[] args)
        {
            var intHolder = new Holder<int>(3,4,5);
            //创建泛型类实例
            var stringHolder=new Holder <string>("a1","b2","c3");
            intHolder.Print();//调用方法
            stringHolder.Print();
        }
    }
}

4.泛型结构

namespace 泛型结构
{
    /*与泛型类相似,泛型结构可以有类型参数和约束。
     泛型结构的规则和条件是和泛型类一样的。*/
    struct PieceOfData<T>
    {
        public PieceOfData(T value)
        {
            _data = value;
        }
        private T _data;
        public T Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var intData=new PieceOfData <int>(10);
            var stringData=new PieceOfData <string>("Hi there.");
            Console.WriteLine("intData={0}",intData .Data);
            Console.WriteLine("stringData={0}",stringData .Data );
        }
    }
}

5.泛型委托

namespace 泛型委托
{
    delegate void MyDelegate<T>/*类型参数*/(T value);//委托形参
    //泛型委托
    class Simple
    {
        static public void PrintString(string s)//方法匹配委托
        {
            Console.WriteLine(s);
        }
        static public void PrintUpperString(string s)//方法匹配委托
        {
            Console.WriteLine("{0}",s.ToUpper ());
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var myDel=new MyDelegate <string>(Simple.PrintString );
            //创建委托的实例
            myDel += Simple.PrintUpperString;//添加方法
            myDel("Hi there.");//调用委托
        }
    }
}

6.另一个泛型委托

namespace 另一个泛型委托
{
    /*声明一个叫做func的委托,它接受带有两个形参
     和一个返回值的方法。方法返回值类型被
     表示为TR,方法参数类型被表示为T1和T2。*/
    public delegate TR func<T1,T2,TR>(T1 p1,T2 p2);//泛型委托
    class Simple
    {
        static public string PrintString(int p1, int P2)//方法匹配委托
        {
            int total = p1 + P2;
            return total.ToString();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var myDel = new func<int, int, string>(Simple .PrintString );//创建委托实例
            Console.WriteLine("Total:{0}",myDel (15,13));//调用委托
        }
    }
}

7.泛型接口

namespace 泛型接口
{
    /*泛型接口允许我们编写参数和接口成员返回类型
     是泛型类型参数的接口。泛型接口的声明和非泛型
     接口的声明差不多,但是需要在接口名称之后的
     尖括号中有类型参数。*/
    interface IMyIfc<T>//泛型接口
    {
        T ReturnIt(T inValue);
    }
    class Simple<S> : IMyIfc<S>//泛型类
    {
        public S ReturnIt(S inValue)//实现泛型接口
        { return inValue; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var trivInt = new Simple<int>();
            var trivString=new Simple <string>();
            Console.WriteLine("{0}",trivInt.ReturnIt (5));
            Console.WriteLine("{0}",trivString .ReturnIt ("Hi there."));
        }
    }
}

8.泛型接口2

namespace 泛型接口2
{
    /*我们可以在非泛型类中实现泛型接口
     */
    interface IMyIfc<T>//泛型接口
    {
        T ReturnIt(T inValue);
    }
    class Simple : IMyIfc<int>, IMyIfc<string>//非泛型类
        /*接口的实现必须唯一,不能出现
         class Simple<S>:IMyIfc<int>,IMyIfc<S>
         * {
         * 。。。。。。。。。。。。。。
         * }的情况*/
    {
        public int ReturnIt(int inValue)//实现int类型接口
        { return inValue; }
        public string ReturnIt(string inValue)//实现string类型接口
        { return inValue; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Simple trivial = new Simple();
            Console.WriteLine("{0}",trivial .ReturnIt (5));
            Console.WriteLine("{0}",trivial .ReturnIt ("Hi there."));
        }
    }
}

9.泛型的协变与逆变

namespace 泛型的逆变与邪变
{
    class Animal { public int Legs = 4;}//基类
    class Dog : Animal { }//派生类
    class Program
    {
        delegate T Factory<out T>();//泛型的邪变
        //delegate T factory<in T>();逆变的格式
        //delegate T Factory<out R,in S,T>();
        /*既有邪变,又有逆变和不变的情况*/
        static Dog makeDog()
        {
            return new Dog();
        }
        static void Main(string[] args)
        {
            Factory<Animal> animalMaker1 = makeDog;
            //隐式强制转换
            Factory<Dog> dogMaker = makeDog;
            //需要out标识符
            Factory <Animal >animalMaker3=new Factory<Dog>(makeDog ) ;
            //需要out标识符
        }
    }
}

 

posted on 2014-05-29 21:43  e心e意  阅读(215)  评论(0)    收藏  举报