C# 泛型
1、什么是泛型
泛型是C#2.0中推出的新语法,泛型不是语法糖,而且由框架升级提供的功能。
我们在编程的时候经常遇到功能非常相似但是数据类型不同的情况,但是我们没有办法,只能分别写多个不同的方法来处理不同的数据类型。那么问题来了,有没有一种办法用同一个方法传入不同的类型参数的办法呢?泛型就是专门来解决这个问题的。
2、泛型有什么用
使用泛型可以最大程度的重用代码、保护类型安全性以及提高性能。泛型最常见的用途是创建集合类List<int>。
泛型包括:泛型类、泛型方法、泛型接口、泛型委托、泛型事件。
泛型类:
1 class GenericClass<T>{}
1 public interface GenericInterface<T>{}
1 public T void Create<T>(T t) 2 { 3 return default(T); 4 }
1 public delegate void GenericDelegate<T>(T t);
3、泛型约束有哪些
where T:struct 类型参数必须是值类型。
where T:class 类型参数必须是引用类型,此约束还应用于任何类、接口、委托或数组类型。
where T:new() 类型参数必须具有公共无参数的构造函数。当与其他约束一起使用时,new() 约束必须最后指定。
where T:<基类名> 类型参数必须是指定的基类或派生自指定的基类。
where T:<接口名> 类型参数必须是指定的接口或实现指定的接口。
4、使用泛型实例,模拟蚂蚁种树
1 public class SuoSuotree 2 { 3 //种植梭梭树需要的能量 4 public int NeedEnergy() 5 { 6 return 17900; 7 } 8 }
1 public class People 2 { 3 //姓名 4 public string name { get; set; } 5 6 //能量 7 public int energy { get; set; } 8 9 public void Plant(SuosuoTree tree) 10 { 11 if(energy< tree.needEnergy()) 12 { 13 Console.WriteLine("能量不足"); 14 } 15 { 16 energy = energy- tree.needEnergy(); 17 Console.WriteLine($"恭喜{name}, 梭梭树种植成功,获得成就!!"); 18 } 19 } 20 }
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 People xiaoming = new People 6 { 7 name = "小明", 8 energy = 200000 9 }; 10 11 xiaoming.Plant(new SuosuoTree()); 12 13 Console.WriteLine("剩余能量:"+xiaoming.energy); 14 15 Console.Read(); 16 17 } 18 }
输出结果为:
现在森林里可以种其他的树了(柠条,樟子松)。那我们添加2个类,修改People类,和Main方法,那有什么办法可以不修改People类的呢?
现在我们创建一个抽象类TreeBase:
1 public abstract class TreeBase 2 { 3 public abstract string GetTreeName(); 4 public abstract int needEnergy(); 5 }
1 public class SuosuoTree: TreeBase 2 { 3 //种植梭梭树需要的能量 4 public override int needEnergy() 5 { 6 return 17900; 7 } 8 public override string GetTreeName() 9 { 10 return "梭梭树"; 11 } 12 }
1 public class NingTiaoTree : TreeBase 2 { 3 //种植柠条需要的能量 4 public override int needEnergy() 5 { 6 return 16930; 7 } 8 public override string GetTreeName() 9 { 10 return "柠条"; 11 } 12 }
1 public class ZhangZiSongTree : TreeBase 2 { 3 //种植樟子松需要的能量 4 public override int needEnergy() 5 { 6 return 146210; 7 } 8 public override string GetTreeName() 9 { 10 return "樟子松"; 11 } 12 }
重新构造后的People:修改后添加了新的树苗,就不用修改People类了。
1 public class People 2 { 3 //姓名 4 public string name { get; set; } 5 6 //能量 7 public int energy { get; set; } 8 9 public void Plant<T>(T tree) where T:TreeBase 10 { 11 if(energy< tree.needEnergy()) 12 { 13 Console.WriteLine("能量不足"); 14 } 15 else 16 { 17 energy = energy- tree.needEnergy(); 18 Console.WriteLine($"恭喜{name},{tree.GetTreeName()}种植成功,获得成就!!"); 19 } 20 } 21 }
小明也可以种不同的树了:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 People xiaoming = new People 6 { 7 name = "小明", 8 energy = 200000 9 }; 10 11 xiaoming.Plant(new SuosuoTree()); 12 xiaoming.Plant(new NingTiaoTree()); 13 xiaoming.Plant(new ZhangZiSongTree()); 14 15 Console.WriteLine("剩余能量:"+xiaoming.energy); 16 17 xiaoming.Plant(new ZhangZiSongTree()); 18 19 Console.Read(); 20 21 } 22 }