zoukankan      html  css  js  c++  java
  • C# 中的泛型

    C# 中的泛型允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候。换句话说,在声明类或方法的时候由于不知道用户要传入什么样类型的参数,所以在传入类型的地方“挖一个坑(“<T>”)",使用它的时候我们再用具体数据类型填上。

    1、泛型类:

    using System;  
    2.using System.Collections.Generic;  
    3.using System.Linq;  
    4.using System.Text;  
    5.  
    6.namespace Example  
    7.{  
    8.    class Data<T> //泛型类  
    9.    {  
    10.        public T[] n_data; //泛型变量  
    11.       public Data(int size) //构造方法,new的时候调用构造方法开辟空间  
    12.        {   
    13.          n_data = new T[size];    
    14.        }  
    15.        //输入  
    16.       public void setdata(int index,T value)  
    17.       {  
    18.           n_data[index] = value;  
    19.       }  
    20.        //输出  
    21.       public T getdata(int x)  
    22.       {   
    23.          return n_data[x];  
    24.       }  
    25.    }  
    26.    class Program  
    27.    {  
    28.        static void Main(string[] args)  
    29.        {  
    30.            Data<int> data = new Data<int>(5);  
    31.            data.n_data[2] = 2;  
    32.           Console.WriteLine(data.n_data[2]);  
    33.        }  
    34.    }  
    35.}  

    2、泛型方法:

    using System;  
    2.using System.Collections.Generic;  
    3.using System.Linq;  
    4.using System.Text;  
    5.  
    6.namespace Example  
    7.{  
    8.    class Data<T> //泛型类  
    9.    {  
    10.        public T[] n_data; //泛型变量  
    11.       public Data(int size) //构造方法,new的时候调用构造方法开辟空间  
    12.        {   
    13.          n_data = new T[size];    
    14.        }  
    15.        //输入  
    16.       public void setdata(int index,T value)  
    17.       {  
    18.           n_data[index] = value;  
    19.       }  
    20.        //输出  
    21.       public T getdata(int x)  
    22.       {   
    23.          return n_data[x];  
    24.       }  
    25.    }  
    26.    class Program  
    27.    {  
    28.        static void Main(string[] args)  
    29.        {  
    30.            Data<int> data = new Data<int>(5);  
    31.            data.n_data[2] = 2;  
    32.           Console.WriteLine(data.n_data[2]);  
    33.        }  
    34.    }  
    35.}  

    泛型约束方法在form 窗口编程上的应用

    private T OpenUniqueMDIChildWindow<T>(Form mdiParent) where T : Form, new()
            {
                foreach (Form subForm in mdiParent.MdiChildren)
                {
                    if (!subForm.GetType().Equals(typeof(T)))
                    {
                        subForm.Close();
                    }
                    else
                    {
                        subForm.Activate();
                        return subForm as T;
                    }
                }
                T newForm = new T();
                newForm.MdiParent = mdiParent;
                //newForm.FormBorderStyle = FormBorderStyle.None;
                //newForm.WindowState = FormWindowState.Maximized;
                //newForm.MaximizeBox = false;
                //newForm.MinimizeBox = false;
    
                newForm.StartPosition = FormStartPosition.CenterScreen;
                newForm.Show();
                return newForm;
            }
    //
    private void btsmiBuildInfo_Click(object sender, EventArgs e)
            {
                OpenUniqueMDIChildWindow<BuildInfo>(this);
            }
    
            private void dtsmiDormInfo_Click(object sender, EventArgs e)
            {
                OpenUniqueMDIChildWindow<DormInfo>(this);
            }

    3、泛型委托

    using System;  
    2.using System.Collections.Generic;  
    3.using System.Linq;  
    4.using System.Text;  
    5.  
    6.namespace Example  
    7.{  
    8.    public delegate void MyDelegate<T>();//泛型委托  
    9.    class Data<T>  
    10.    {  
    11.        private T a;  
    12.        private T b;  
    13.        public void setvalue(T x, T y)  
    14.        {  
    15.            a = x;  
    16.            b = y;  
    17.        }  
    18.        //swap方法,ref是按地址传递  
    19.        public void swap()  
    20.        {  
    21.            T temp;  
    22.            temp = a;  
    23.            a = b;  
    24.            b = temp;  
    25.        }  
    26.        public void printvalue()  
    27.        {  
    28.            Console.WriteLine(a + "	" + b);  
    29.  
    30.        }  
    31.  }  
    32.      class program  
    33.       {   
    34.         static void Main(string[] args)  
    35.          {  
    36.            Data<string> data = new Data<string>();  
    37.            data.setvalue("HC","666");  
    38.            MyDelegate<string> my = new MyDelegate<string>(data.swap);  
    39.            my += data.printvalue;  
    40.            my();  //结果 666  HC        
    41.           }  
    42.          
    43.       }  
    44.        
    45.   }  

    泛型类中数据类型的约束 程序员在编写泛型类时,总是会对通用数据类型T进行有意或无意地有假想,也就是说这个T一般来说是不能适应所有类型,但怎样限制调用者传入的数据类型呢?这就需要对传入的数据类型进行约束,约束的方式是指定T的祖先,即继承的接口或类。因为C#的单根继承性,所以约束可以有多个接口,但最多只能有一个类,并且类必须在接口之前。这时就用到了C#2.0的新增关键字:

    public class Node<T, V> where T : Stack, IComparable

            where V: Stack

        {...}

    以上的泛型类的约束表明,T必须是从Stack和IComparable继承,V必须是Stack或从Stack继承,否则将无法通过编译器的类型检查,编译失败。

    通用类型T没有特指,但因为C#中所有的类都是从object继承来,所以他在类Node的编写中只能调用object类的方法,这给程序的编写造成了困难。比如你的类设计只需要支持两种数据类型int和string,并且在类中需要对T类型的变量比较大小,但这些却无法实现,因为object是没有比较大小的方法的。 了解决这个问题,只需对T进行IComparable约束,这时在类Node里就可以对T的实例执行CompareTo方法了。这个问题可以扩展到其他用户自定义的数据类型。

    如果在类Node里需要对T重新进行实例化该怎么办呢?因为类Node中不知道类T到底有哪些构造函数。为了解决这个问题,需要用到new约束:

    public class Node<T, V> where T : Stack, new()

            where V: IComparable

    需要注意的是,new约束只能是无参数的,所以也要求相应的类Stack必须有一个无参构造函数,否则编译失败。

    C#中数据类型有两大类:引用类型和值类型。引用类型如所有的类,值类型一般是语言的最基本类型,如int, long, struct等,在泛型的约束中,我们也可以大范围地限制类型T必须是引用类型或必须是值类型,分别对应的关键字是class和struct:

    public class Node<T, V> where T : class

            where V: struct

    泛型方法 泛型不仅能作用在类上,也可单独用在类的方法上,他可根据方法参数的类型自动适应各种参数,这样的方法叫泛型方法。看下面的类:

    public class Stack2

        {

            public void Push<T>(Stack<T> s, params T[] p)

            {

                foreach (T t in p)

                {

                    s.Push(t);

                }

            }

    }

    原来的类Stack一次只能Push一个数据,这个类Stack2扩展了Stack的功能(当然也可以直接写在Stack中),他可以一次把多个数据压入Stack中。其中Push是一个泛型方法,这个方法的调用示例如下:

    Stack<int> x = new Stack<int>(100);

        Stack2 x2 = new Stack2();

        x2.Push(x, 1, 2, 3, 4, 6);

        string s = "";

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

        {

            s += x.Pop().ToString();

        }    //至此,s的值为64321


     

  • 相关阅读:
    win32com操作word(3):导入VBA常量
    win32com操作word(2):常用用法
    win32com操作word(1):几个重要的对象(28.35)
    文件操作:os模块与os.path模块
    python上下文管理器
    OpenStack基础知识-单元测试工具介绍
    python测试模块-pytest介绍
    Python包管理工具setuptools详解及entry point
    OpenStack基础知识-项目打包的步骤
    OpenStack基础知识-打包知识点
  • 原文地址:https://www.cnblogs.com/wenjie0904/p/7912878.html
Copyright © 2011-2022 走看看