C# 泛型

C#中有泛型类、泛型方法、泛型接口、泛型委托。下面先介绍前3种类型。

1.泛型类、泛型方法:

 1 /// <summary>
 2     /// 泛型类和泛型方法
 3     /// </summary>
 4     /// <typeparam name="T"></typeparam>
 5     class MyClass<T>
 6     {
 7         public void Say(T msg)
 8         {
 9             Console.WriteLine(msg);
10         }
11     }

实例化这个类的时候,代码如下:

1             MyClass<string> mc1 = new MyClass<string>();
2             mc1.Say("yzk");
3 
4             MyClass<int> mc2 = new MyClass<int>();
5             mc2.Say(20);

可以看到Say()方法中的参数类型早在实例化MyClass时就约束好了。

上面的代码中是把泛型方法写在泛型类中了,也可以把泛型方法写在普通类中。

 1 /// <summary>
 2     /// 普通类中的泛型方法
 3     /// </summary>
 4     class MyClass1
 5     {
 6         public string Name { get; set; }
 7         public int Age { get; set; }
 8         public void Say<T>(T msg)
 9         {
10             Console.WriteLine(msg);
11         }
12     }

实例化这个类的时候,代码如下:

1             MyClass1 mc1 = new MyClass1();
2             mc1.Name = "yzk";
3             mc1.Age = 18;
4             mc1.Say<int>(10);
5             mc1.Say<string>("hello");
6             mc1.Say<string>(mc1.Name);

可以看到,在调Say方法的时候,<>中写什么类型,后面的参数就必须是什么类型。

2.泛型接口

 1 class Person:IComparable<Person>
 2     {
 3         public string Name { get; set; }
 4         public int Age { get; set; }
 5 
 6         public int CompareTo(Person other)
 7         {
 8             return other.Age - this.Age;
 9         }
10     }

上面的代码,首先让Person类实现了泛型的IComparable接口,可以看到里面的CompareTo方法参数也是Person类型,就不用再转换other了,这是实现泛型接口的好处。与之类似的还有IComparer<T>接口,看下面2个比较器:

 1 class SortByName:IComparer<Person>
 2     {
 3 
 4         public int Compare(Person x, Person y)
 5         {
 6             return y.Name.Length - x.Name.Length;
 7         }
 8     }
 9 
10     class SortByAge:IComparer<Person>
11     {
12 
13         public int Compare(Person x, Person y)
14         {
15             return x.Age - y.Age;
16         }
17     }

泛型中的类型推断,代码如下:

 1 /// <summary>
 2     /// 普通类中的泛型方法
 3     /// </summary>
 4     class MyClass1
 5     {
 6         public string Name { get; set; }
 7         public int Age { get; set; }
 8         public void Say<T>(T msg)
 9         {
10             Console.WriteLine(msg);
11         }
12     }

但是在使用的时候,是这个样子的:

1             MyClass1 mc1 = new MyClass1();
2             mc1.Name = "yzk";
3             mc1.Age = 18;
4             mc1.Say(10);
5             mc1.Say("hello");
6             mc1.Say(mc1.Name);

可以看到,虽然Say方法是泛型的,但是调用的时候,不写参数类型,也能自动推断,这就是泛型中的类型推断。

关于泛型方法重载的问题:

 1 class MyClass4
 2     {
 3         //如果在MyClass4写了泛型(MyClass4<T>),那么下面的Show方法可以写成这个样子:Show(T msg),不必要写<T>
 4         public void Show<T>(T msg)
 5         {
 6             Console.WriteLine(msg);
 7         }
 8 
 9         public void Show(string msg)
10         {
11             Console.WriteLine(msg);
12         }
13     }

在实例化上面的类的时候,我们这么写:

1             MyClass4 mc4 = new MyClass4();
2             mc4.Show("abc");

那么这个Show到底是调用了泛型方法,还是普通方法呢?且看编译器是如何编译的

    new MyClass4().Show("abc");

编译器(遵循简单方便原则)看到有不带泛型的方法就直接调用了。而如果这么写就是调用泛型方法:

mc4.Show<string>("abc");

编译后的代码如下:

  new MyClass4().Show<string>("abc");

 

泛型约束:

在写泛型的时候,可以约束泛型必须是某个类型或继承至某个类型或者实现某个接口,语法如下:

1 class MyClass<T,K,V,w,Y,D>
2   where T:struct  //约束T必须是值类型;
3   where K:class  //约束K必须是引用类型。
4   where V:Icomparable  //约束V必须是实现Icomparable接口的类型或其子类类型.
5   where w:Person    //约束w必须是Person类型或其子类类型.
6   where Y:K     //约束Y必须是K类型或其子类类型。
7   where D:new()   //约束参数必须有无参的公共构造函数。放在最后。

posted on 2014-07-22 09:44  chens2865  阅读(236)  评论(0编辑  收藏  举报

导航