C#高级编程3十一天-泛型总结

C#高级编程三十一天----泛型总结

C#泛型总结

C#中的所谓的泛型程序设计和C++中相应的模版类似.

泛型方法

C#中的泛型方法是指使用了类型参数的方法成员,案例:

   static void Main(string[] args)

        {

            int a=1;

            int b=2;

            Swap<int>(ref a,ref b);

            //Swqp(ref a,ref b);效果和上面一句相同

            Console.WriteLine("a = {0},b = {1} ",a,b);

        }

        public static void Swap<T>(ref T x,ref T y)

        {

            T temp=x;

            x=y;

            y=temp;

        }

在使用泛型方法的时候需要注意几点:

1.泛型方法可以对其参数类型进行类型限制其中包括:主要限制,次要限制,函数限制

2.C#中是不允许对类的构造函数,属性,事件,索引函数和操作符等特殊函数定义为泛型方法的.

3.泛型方法也可以被定义为虚方法,重载方法,抽象方法或者密封方法等,泛型方法也可以实现override重载,也能利用其实现多态么还有一点就是在派生类中重载基类中的泛型方法时,会自动继承基类中的泛型方法的所有类型限制,没有必要再去重新声明一遍,当然重新声明也是错误的.

4.泛型方法是可以通过委托机制来调用的,其实现机制有两种,分别是:”普通委托”和”泛型委托”

案例:

 public static void Swap<T>(ref T x,ref T y)

        {

            T temp=x;

            x=y;

            y=temp;

        }

        public static void Clear<T>(ref T x, ref T y)

        {

            x = default(T);

            y = default(T);

        }

补充:在泛型类和方法中,在预先未知以下情况时,如何将默认值分配给参数化类型T:

1.T是引用类型还是值类型

2.如果T是值类型,则它是数值还是结构

3.如果T是引用类型,t=null有效,T为数值类型,t=0才有效,若为结构,则要符合结构中的每个类型.

 

 

所以在我们不确定的情况下,使用default关键字,系统会自动的为他分配默认值.

public T Delete(T t)

{

T temp=default(T);

//action

return temp;

}

因为事先不知道T是何种类型,可能是int型可能是string类型,或者是结构.

在这种情况下,要返回函数结果时,使用default就可以返回一个默认值了,因为都是系统为我们做这些.

 

普通委托:

public delegate void fun(ref int x,ref int y);

int a=1;

int b=2;

fun fun1;

fun1=Swap<int>;

fun1(ref a, ref b);

 

泛型委托:

public delegate void fun<T>(ref T x,ref T y);

fun<int> fun2;

fun2=Swap<int>;

fun2(ref a, ref b);

 

 

 

泛型类和泛型接口

案例:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ConsoleApplication11

{

    class Program

    {

        static void Main(string[] args)

        {

            

        }

       

    }

    public class LinkNode<T>

    {

        protected T data;

        protected LinkNode<T> next;

        public T Data

        {

            get { return data; }

            set { data = value; }

        }

        public LinkNode<T> Next

        {

            get { return next; }

            set { next = value; }

        }

        public LinkNode()

        {

            data = default(T);

        }

        public LinkNode(T t)

        {

            data = t;

        }

        public static LinkNode<T> operator >>(LinkNode<T> node, int n)

        {

            LinkNode<T> node1 = new LinkNode<T>();

            node1 = node;

            for (int i = 0; i < n; i++)

            {

                node1 = node.next;

            }

            return node1;

        }

        public static bool operator ==(LinkNode<T> t1, LinkNode<T> t2)

        {

            //return (t1.Data ==t2.Data);

            //错误不能直接将比较符运用到未知类型的T类型中

            //但是可以直接利用object类中的比较方法如Equals();

            return (t1.Data.Equals(t2.Data));

        }

    }

    

}

 

分析:

1.泛型类的构造函数名称是与类名同名的,并不包括类型参数

2.不能随意的在泛型类中将比较运算符运用于参数类型的对象中,这样一定会报错,但是如果是运用object类中的相关方法是可行的的.

3.在一个泛型类中可以使用多个泛型参数

4.泛型类本身不能拥有任何东西,只有泛型类的构造类型和其具体实例才能拥有成员方法或数据成员.而在C#中泛型类中的静态成员则是属于该泛型类的构造类型

5.无论是在写泛型类,泛型接口或是泛型方法时都可以加上类型限制,C#支持在泛型定义过程中通过where关键字来对类型参数进行限制,限制方式主要包括:主要限制(可以限制为struct值类型或者class引用类型),次要限制(限制该类型参数必须从指定的基类或接口继承而来),构造函数限制(要求类型参数的目标类型必须提供一个无参的构造函数),这里的类型限制在C#的程序设计中提供了极大的方便,这是C++中的模板不能匹敌的,但同时牺牲了一些灵活性.

6.由泛型类型所引发的泛型类的继承问题,在泛型类之间的继承中有一天基本的原则就是:开放类型不能作为封闭类型的基类.    也就是说,在普通类继承泛型类时,非泛型的普通类是不能直接继承自泛型类的,但能继承自泛型类的封闭构造函数.就是在继承的过程中类的”开放性”不能变小,但能变大或者不变.