泛型

一、引言

前面我们学过泛型集合List,非泛型集合ArrayList,了解到创建List集合的时候,需要指定类型,并且只能存储这种类型的数据,相比ArrayList能存储各种类型的数据而言,效率更高(避免了装箱拆箱)。那我们声明List<int>集合的时候,开始为何不直接设计一个ListInt类,而要设计成List<T>呢?因为List中的方法,算法其实是一样的,这样可以避免重复,并且,如果我要在List中保存自己自定义的类的对象的时候,(比如Person),无法再像开始那样,有预见性的设计出一个ListPerson类。所以需要引入泛型。

二、泛型类

下面看一个具体的例子:

 1 public class MyClass
 2     {
 3         public string [] Names { get; set; }
 4 
 5         public MyClass(string [] names)
 6         {
 7             this.Names = names;
 8         }
 9 
10         public void Show()
11         {
12             foreach (string item in Names)
13             {
14                 Console.WriteLine(item);
15             }
16         }
17     }
View Code

在控制台程序中输出数组中的元素:

 1 static void Main(string[] args)
 2         {
 3 
 4             string[] names = { "A","B","C","D"};
 5 
 6             MyClass mc = new MyClass(names);
 7             mc.Show();
 8 
 9             Console.ReadKey();
10         }
View Code

现在需求改动,想把string类型的数组改成int类型的,这时候,我们只好把MyClass中和控制台中所有关于类型的地方全部改下,但是其他地方丝毫不用改。这当然可以,只是有点麻烦,有没有其他方式,不用改动MyClass中的东西呢?

这时候可以泛型。改动后的代码如下:

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5 
 6             string[] names = { "A","B","C","D"};
 7             //MyClass<string> mc = new MyClass<string>(names);
 8 
 9             //如果要改成Int类型的数组,只要作如下改动
10             MyClass<int> mc = new MyClass<int>(new int[] {1,2,3,4 });
11             
12             mc.Show();
13 
14             Console.ReadKey();
15         }
16     }
17 
18     public class MyClass<T>
19     {
20         public T [] Names { get; set; }
21 
22         public MyClass(T [] names)
23         {
24             this.Names = names;
25         }
26 
27         public void Show()
28         {
29             foreach (T item in Names)
30             {
31                 Console.WriteLine(item);
32             }
33         }
34     }
View Code

这里我们能明显看到泛型的方便了。

三、泛型接口

 有以上的基础,看泛型接口就可以容易了,直接上代码:

1  public interface IFlyable<T>
2     {
3         void Fly(T t);
4     }
View Code

但是要注意:

1.如果是实例类实现泛型接口,泛型接口必须指定泛型的类型:

1  public class SpiderMan : IFlyable<string>
2     {
3         public void Fly(string t)
4         {
5             Console.WriteLine(t);
6         }
7     }
View Code

2.如果是泛型类,实现泛型接口的时候必须指定泛型的类型:

1 public class SpiderMan<T> : IFlyable<T>
2     {
3         public void Fly(T t)
4         {
5             throw new NotImplementedException();
6         }
7     }
View Code

四、泛型方法

1 public class Person
2     {
3         //方法后面加个<T>就是泛型方法
4         public void Show<T>(T t)
5         {
6             Console.WriteLine(t);
7         }
8     }
View Code

main函数中的代码:

1   Person p = new Person();
2             p.Show("aaa");//方法名称后面不加<T>,编译器会根据传入的数据,自动推断
3             p.Show<string>("aaa");//
4             p.Show(2);
View Code

五、泛型委托

 首先写几委托和方法:

1 public delegate void MDelegate(string str);
1 public delegate void IDelegate(int i);
2     public delegate void MDelegate(string str);
3     public delegate void DDelegate(double d);
View Code

方法:

 1 static void M1(int i)
 2         {
 3             Console.WriteLine(i);
 4         }
 5 
 6         static void M2(string s)
 7         {
 8             Console.WriteLine(s);
 9         }
10 
11         static void M3(double d)
12         {
13             Console.WriteLine(d);
14         }
View Code

我们要使用MDelegate这个委托只能传入方法签名一致的方法M2,如果我想调用M1,M3方法的话,必须再写两个委托,太麻烦。

1 MDelegate m = M2;
2             m("124");
3 
4             IDelegate i = M1;
5             i(1);
6 
7             DDelegate d = M3;
8             d(1.2);
View Code

 但是改成泛型委托,情况就变得简单很多了

1 public delegate void DynamicDelegate<T>(T t);
View Code

用上面泛型委托,可以调用M1,M2,M3方法,如下:

1 DynamicDelegate<int> i = M1;
2             i(1);
3 
4             DynamicDelegate<string> s = M2;
5             s("afsd");
6 
7             DynamicDelegate<double> d = M3;
8             d(1.2);
View Code
原文地址:https://www.cnblogs.com/wesley168/p/6782815.html