码迷,mamicode.com
首页 > Windows程序 > 详细

C#之泛型

时间:2019-01-09 22:46:37      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:show   技术   intro   泛型   delegate   img   多重   set   cte   

---恢复内容开始---

泛型即一个方法可以传递多种不同的类型的时候,就用泛型。泛型是C#2.0语法新特性,也是.net framework框架升级的结果。

 //引入泛型
    public class IntroduceGeneric
    {
        //普通方法
        public void ShowInt(int i)
        {
            Console.WriteLine(i);
        }
        public void ShowString(string s)
        {
            Console.WriteLine(s);
        }
        public void ShowDateTime(DateTime t)
        {
            Console.WriteLine(t);
        }
        //泛型方法
        public void Show<T>(T t)
        {
            Console.WriteLine(t);
        }
    }
static void Main(string[] args)
        {
            int i = 2;
            string s = "abc";
            DateTime dateTime = DateTime.Now;
            IntroduceGeneric introduceGeneric = new IntroduceGeneric();
            Console.WriteLine("普通方法");
            introduceGeneric.ShowInt(i);
            introduceGeneric.ShowString(s);
            introduceGeneric.ShowDateTime(dateTime);
            Console.WriteLine("泛型方法");
            introduceGeneric.Show<int>(i);
            introduceGeneric.Show<String>(s);
            introduceGeneric.Show<DateTime>(dateTime);
            
        }

从上面两段代码可以看出,用一个泛型方法可以代替多种普通的方法。这时候可以有人想到用object类型传参,下面就试试obejct。

   //泛型方法
        public void Show<T>(T t)
        {
            Console.WriteLine(t);
        }
        //基于object类型传参
        public void ShowObject(object o)
        {
            Console.WriteLine(o);
        }
   Console.WriteLine("泛型方法");
            introduceGeneric.Show<int>(i);
            introduceGeneric.Show<String>(s);
            introduceGeneric.Show<DateTime>(dateTime);
            Console.WriteLine("用object类型传参方法");
            introduceGeneric.ShowObject(i);
            introduceGeneric.ShowObject(s);
            introduceGeneric.ShowObject(dateTime);

运行结果

技术分享图片

从运行结果可以看出 ,泛型方法和object传参没有什么区别。其实很容易理解,因为object 是一切类型的父类。下面我们从性能方面来比较泛型和object传参方法。

 

 public class PerformanceTest
    {
        public static IntroduceGeneric introduceGeneric = new IntroduceGeneric();
        public static void CommonMethod()
        {
            Console.WriteLine("执行10000000次普通方法消耗时间");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int i = 10;
            for (var t = 0; t < 10000000; t++)
            {
                introduceGeneric.ShowInt(i);
            }
            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
        }
        public static void GenericMethod()
        {
            Console.WriteLine("执行10000000次泛型方法消耗时间");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int i = 10;
            for (var t = 0; t < 10000000; t++)
            {
                introduceGeneric.Show<int>(i);
            }
            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
        }
        public static void ObjectMethod()
        {
            Console.WriteLine("执行10000000次object参数方法消耗时间");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            int i = 10;
            for (var t = 0; t < 10000000; t++)
            {
                introduceGeneric.ShowObject(i);
            }
            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
        }


    }

为了便于查看,将方法里面的代码置空,即不输出上文中的内容。。下面就看比较结果

技术分享图片

可以看出  泛型方法和普通方法几乎一样  甚至性能还由于普通方法  而object参数方法 则消耗的时间大概是泛型方法的两倍。原因是object在上述过程中进行了大量的装箱与拆箱操作。

泛型除了应用与泛型方法 还可以是泛型类、泛型接口 、泛型委托。

public class GenericClass<T>
    {
        public T t { get; set; }
        public void  Fun()
        {
            this.t = default(T);
            Console.WriteLine(t?.ToString());
        }
    }


 Console.WriteLine("泛型类");
            GenericClass<int> genericClass = new GenericClass<int>();
            genericClass.Fun();
            GenericClass<string> genericClass2 = new GenericClass<string>();
            genericClass2.Fun();
            GenericClass<DateTime> genericTest3 = new GenericClass<DateTime>();
            genericTest3.Fun();

测试结果:

技术分享图片

泛型类的继承

 public class GenericChildClass : GenericClass<int>
    {
    }
    public class GenericChildClass2<T, S> : GenericClass<T>
    {
    }

//注意当子类不是泛型类的时候,父类的泛型一定要指明具体的类型。如果不指明,父类的类型不能确定
//单子类中包含父类中的泛型类型时,父类可以不指明,以为这时唯一一个子类对应唯一一个父类

泛型接口,泛型委托

//泛型接口
    public interface IGeneric<T>
    {
        void IFun(T t);
    }
    //泛型委托
    public delegate void GenericDelegate<T>(T t);

泛型约束

 public class People
    {
        public string Name { get; set; }
        public int Age { get; set; }

       
    }
    //泛型约束
    public class GenericConstraint
    {
        //要求定义一个方法实现打印people的姓名和名称
        public void CommonPrint(People people)
        {
            Console.WriteLine($"姓名:{people.Name} 年龄:{people.Age}");
        }
        public void GenericPrint<T>(T t) where T : People
        {
            Console.WriteLine($"姓名:{t.Name} 年龄:{t.Age}");
            
        }
        public void ObjectPrint(object t)
        {
            //Console.WriteLine($"姓名:{t.Name} 年龄:{t.Age}");报错  编译不能通过
        }
    }
    //泛型约束实现了可以访问泛型约束了的公开方法和属性、字段
    //object参数方法则不行  这就是我们常说的类型安全问题

泛型约束的种类  

1.基类约束

2.接口约束

3.值类型约束

4.引用类型约束

5.无参构造函数约束

//约束种类
        public void GenericType<T>(T t)
            //where T : new()//基类约束 约束类型必须包含无参构造函数  其他有参构造函数可有可无
            //where T:struct// 值类型约束
            //where T:class//引用类型约束
            //where T:ISport//接口约束
            where T:People,ISport //多重约束,既是People类型(含子类) 并且实现了ISport接口(子类父类都可以)
        {
            
        }

 

---恢复内容结束---

C#之泛型

标签:show   技术   intro   泛型   delegate   img   多重   set   cte   

原文地址:https://www.cnblogs.com/hzpblogs/p/10247262.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!