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()   //约束参数必须有无参的公共构造函数。放在最后。

你可能感兴趣的:(C#)