zoukankan      html  css  js  c++  java
  • C# 泛型,泛型约束

    泛型主要是为了解决代码的复用性

    在泛型出现之前,如果需要用到不同的参数类型,但是方法体一样的时候,需要定义多个不同类型参数的方法,这样有太多的重复代码如下

           public static void ShowInt(int iParameter)
            {
                Console.WriteLine("类名称:"+typeof(TestFunctionClass).FullName+",参数类型:"+ iParameter.GetType().ToString() + ",参数Value:"+iParameter);
            }
    
            public static void ShowString(string sParameter)
            {
                Console.WriteLine("类名称:" + typeof(TestFunctionClass).FullName + ",参数类型:" + sParameter.GetType().ToString() + ",参数Value:" + sParameter);
            }
    
            public static void ShowDate(DateTime dParameter)
            {
                Console.WriteLine("类名称:" + typeof(TestFunctionClass).FullName + ",参数类型:" + dParameter.GetType().ToString() + ",参数Value:" + dParameter);
            }

    在Main方法中进行调用

     Console.WriteLine("最开始展示不同类型参数的信息的时候,需要定义多个不同类型的方法,而方法内容是几乎一样的");
      TestFunctionClass.ShowInt(1);
      TestFunctionClass.ShowString("aaa");
      TestFunctionClass.ShowDate(DateTime.Now);
      Console.ReadLine();

    输出结果

    后来发现使用里氏替换原则,任何使用父类的地方可以使用子类来进行替换,于是有了下面这种写法(object是任何子类的父类)

     public static void ShowObject(object oParameter)
     {
         Console.WriteLine("类名称:" + typeof(TestFunctionClass).FullName + ",参数类型:" + oParameter.GetType().ToString() + ",参数Value:" + oParameter);
     }

    在主方法中可以直接传递

     Console.WriteLine("后来发现通过里氏替换原则,任何父类出现的地方可以用子类来进行替换,可以节省大部分代码");
     TestFunctionClass.ShowObject(2);
     TestFunctionClass.ShowObject("bbb");
     TestFunctionClass.ShowObject(DateTime.Now);
     Console.WriteLine("但是这样出现一个问题,出现类类型之间的转换,发生了装箱操作,这样使性能得到了非常大的损耗,(值类型转换为引用类型)");

    输出结果

    这个时候出现了泛型,泛型是在定义的时候,不直接声明类型,直到调用的时候再去指定,延时声明的作用,避免了装箱操作,减少了性能损耗

            public static void ShowFanXing<T>(T tParameter)
            {
                Console.WriteLine("类名称:" + typeof(TestFunctionClass).FullName + ",参数类型:" + tParameter.GetType().ToString() + ",参数Value:" + tParameter);
            }

    在主方法中调用

         TestFunctionClass.ShowFanXing<int>(3);
            TestFunctionClass.ShowFanXing<string>("ccc");
            TestFunctionClass.ShowFanXing<DateTime>(DateTime.Now);
            Console.WriteLine("使用泛型的时候性能和使用普通方法类似,远大于通过object(里氏替换原则)的性能(前提:如果发生了装箱操作的时候");

    输出结果

    这个时候,泛型的定义知道了,但是咱们发现好像泛型没有什么意义,在方法内只能使用的还是基类的一些属性和方法

    这个时候需要引入一个东西,泛型约束,通过泛型约束,咱们可以在泛型方法(泛型类)中使用约束的属性和方法

    先声明一些基础类

        public class Pepple
        {
            public int Age { get; set; }
    
            public string Name { get; set; }
    
            public string SayHi()
            {
                return "Hi,My Name is" + Name + ",My Age Is " + Age;
            }
        }
    
        public class Chinese : Pepple, ISiChuan
        {
            public string Dialect { get; set; }
            public string Food()
            {
                return "火锅";
            }
        }
    
        public class Japanese : Pepple, IGuangDao
        {
            public string ViewSakura()
            {
                return "美しい桜";
            }
        }
    
        public interface ISiChuan
        {
            string Dialect { get; set; }
    
            string Food();
        }
    
        public interface IGuangDao
        {
            string ViewSakura();
        }

    泛型约束,方法

     public static void ShowPeople<T>(T tParameter) where T : Pepple
     {
         Console.WriteLine("名字:" + tParameter.Name + ",年龄:" + tParameter.Age);
         Console.WriteLine("说话:" + tParameter.SayHi());
     }

    在主方法中可以进行调用

       Pepple people = new Pepple()
         {
             Age = 1,
             Name = "People Name"
         };
         //里氏替换原则
         Pepple chinese = new Chinese()
         {
              Age = 1,
              Name = "张三"
          };
    
          TestFunctionClass.ShowPeople<Pepple>(people);
          TestFunctionClass.ShowPeople<Pepple>(chinese);
          Console.WriteLine("这个时候还有一个问题,虽然用了泛型约束,可以使用约束类的属性和方法,但是,子类的一些特性还是不能访问,这个时候出现了接口约束");
          Console.ReadLine();

     输出结果

    泛型接口约束

    public static void ShowPeopleDetail<T>(T tParameter) where T : Pepple, ISiChuan
    {
         Console.WriteLine("名字:" + tParameter.Name + ",年龄:" + tParameter.Age);
         Console.WriteLine("说话:" + tParameter.SayHi());
         Console.WriteLine("喜欢吃:" + tParameter.Food());
    }

    执行结果

    结束

  • 相关阅读:
    PHP函数
    git (1)
    JavaScript(4)
    javascript-DOM(3)
    JavaScript-DOM(2)
    [转]分布式架构知识体系
    Mysql中查看每个IP的连接数
    Git常用命令备忘录
    windows下用vscode写C++
    sudo cd为什么不能够执行?
  • 原文地址:https://www.cnblogs.com/notyourdog/p/10412842.html
Copyright © 2011-2022 走看看