美文网首页
C#重温—泛型

C#重温—泛型

作者: 高调的小丑 | 来源:发表于2018-08-07 17:16 被阅读15次

    泛型定义

    泛型就是泛指的类型。这是在.NET Framework 2.0出现的语法。

    泛型的好处:

    • 类型的安全性
    • 代码的可重用性
    • 提升效率(避免了不必要的装箱拆箱)。

    下面我分别来说明这三点。

    1. 泛型会约束变量的类型。比如ArryList可以添加任意类型的值,而List<int>只能添加int类型的值
    ArrayList list = new ArrayList();
    list.Add("hello");
    list.Add(1111);
    
     List<int> list = new List<int>();
    list.Add(11);
    
    1. 定义了一个泛型类Generic来提高代码可重用性,在指定的时候是泛指类型,在使用的时候就需要特定类型。
    static void Main(string[] args)
    {
      Generic<string> gs1 = new Generic<string>();
      gs1.Name = "hello world";
      Console.WriteLine(gs1.Name);
    
      Generic<int> gs2 = new Generic<int>();
      gs2.Name = 111;
      Console.WriteLine(gs2.Name);
    
      Generic<Task> gsTask = new Generic<Task>();
      gsTask.Name = Task.Run(() => {
        Console.WriteLine("这是一个Task");
      });
    }
    
    public class Generic<T>
    {
      public T Name=default(T);
    }
    
    1. 泛型会固定类型,在使用的时候就知道是什么类型了,避免了不必要的类型转换。
    object a = 18;
    int b = (int)a;
    //泛型
    int c = GetValue<int>(19);
    string b = GetValue<string>("hello");
     public static T GetValue<T>(T a)
    {
      return a;
    }
    

    泛型约束

    话不多少,先看代码

    static void Main(string[] args)
    {
        Generic<Fanxing> g = newGeneric<Fanxing>();
        Fanxing fx = new Fanxing();
        fx.Name = "Jack";
        g.Name = fx;
        Console.WriteLine(g.Name.Name);
        
        Generic<Base> gsBase = newGeneric<Base>();
        Base b = new Base();
        b.Name = "Curry";
        gsBase.Name = b;
        Console.WriteLine(gsBase.Name.Name);
        
        Console.ReadKey();
    }
    
    public class Generic<T> where T :Base
    {
        public T Name=default(T);
    }
    public class Base
    {
        public string Name { get; set; }
    }
    public class Fanxing:Base
    {
        public new string Name { get; set; }
    }
    

    泛型默认会有一个约束,当我们不显示的声明时,这个约束不存在。但当我们显示的声明的时候,这个约束就会执行。

    从代码中可以看出where T : Base就是这个特别的约束。这个约束限制了泛型的类型,要求我们Generic类的指定类型T必须是Base或者继承Base类的类型。

    约束 说明
    T:struct 类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。
    T:class 类型参数必须是引用类型,包括任何类、接口、委托或数组类型。
    T:new() 类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。
    T:<基类名> 类型参数必须是指定的基类或派生自指定的基类。
    T:<接口名称> 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
    T:U 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束。

    泛型函数

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

    static void Main(string[] args)
    {
        Person p = new Person();
        p.GetInfo<int>(11);
        p.GetInfo<string>("11");
        Console.ReadKey();
    }
    
    public class Person
    {
        public void GetInfo<T>(T obj)
        {
            if (obj.GetType()== typeof(int))
            {
                Console.WriteLine("这是一个int类型:"+ obj.GetType());
            }else if (obj.GetType() == typeof(string))
            {
                Console.WriteLine("这是一个string类型");
            }
        }
    }
    

    泛型委托Action和Func

    1. Action是无返回值的泛型委托,Action至少0个参数,至多16个参数,无返回值。
    Action<string, int> action = (a, b) => Console.WriteLine(a+b); 
    action("hello", 18);
    
    1. Func是有返回值的泛型委托,Func至少0个参数,至多16个参数,根据返回值泛型返回。必须有返回值,不可void
    Func<int, int, int> add= (x, y) => x + y;
    int result = add(1, 2);
    

    参考:C#语法——泛型的多种应用

    相关文章

      网友评论

          本文标题:C#重温—泛型

          本文链接:https://www.haomeiwen.com/subject/rdzwvftx.html