用C#解释外行风格的generics?

重复C#中的“”语法是什么


其实我想知道“我为什么以及何时应该使用generics?”。

有什么需要呢?

generics是一种在C#中确保编译时类型安全的方法。

示例 – Pre-Generics:

class Person { string name; string lastname; public Person(string _name ) { this.name = _name; } } class ClientCode { public static void Main() { //create a list of person ArrayList personList = new ArrayList(); Person p1 = new Person("John"); Person p2 = new Person("Ram"); personList.Add(p1); personList.Add(p2); // BUT, someone can do something like: // ArrayList does not stop adding another type of object into it object q = new object(); personList.Add(q); // while accessing personlist foreach(object obj in personlist) { Person p = obj as Person; // do something, for person // But it will fail for last item in list 'q' since its is not person. } } } 

示例 – 后generics:

 class ClientCode { public static void Main() { //create a list of person List personList = new List(); Person p1 = new Person("John"); Person p2 = new Person("Ram"); personList.Add(p1); personList.Add(p2); // Someone can not add any other object then Person into personlist object q = new object(); personList.Add(q); // Compile Error. // while accessing personlist, No NEED for TYPE Casting foreach(Person obj in personlist) { // do something, for person } } } 

generics允许您以与参数允许您对值进行参数化的方式相同的方式对代码进行参数化。 这可能并不能解释很多,所以让我们一步一步地完成它:

想象一下,你想要一个程序来打印“我喜欢兔子”。 你写这个:

 static void Main() { ILikeBunnies(); } void ILikeBunnies() { Console.WriteLine("I like bunnies"); } 

一切都很好。 但你也喜欢奶酪,所以现在你有:

 static void Main() { ILikeBunnies(); ILikeCheese(); } void ILikeBunnies() { Console.WriteLine("I like bunnies"); } void ILikeCheese() { Console.WriteLine("I like cheese"); } 

您注意到您的两个function几乎完全相同。 您希望重用相同的function,但为您喜欢的内容提供不同的

 static void Main() { ILike("bunnies"); ILike("cheese"); } void ILike(string what) { Console.WriteLine("I like " + what); } 

这就是函数参数的用途:它们允许您重用具有不同值的相同代码。

generics就是这样,但不是传递不同的值,而是传入类型 。 假设你有代码需要将两个字符串捆绑到一个数组中:

 static void Main() { string[] s = Pair("a", "b"); } string[] Pair(string a, string b) { return new string[] { a, b }; } 

很好,花花公子。 后来你意识到你还需要将int打包成一个数组:

 static void Main() { string[] s = Pair("a", "b"); int[] i = Pair(1, 2); } string[] Pair(string a, string b) { return new string[] { a, b }; } int[] Pair(int a, int b) { return new int[] { a, b }; } 

就像以前一样,我们可以看到那里有一堆冗余。 我们需要的是一个返回一对任何东西的函数,以及一种传递我们想要的一对类型的方法。 这是generics的用途:

 static void Main() { string[] s = Pair("a", "b"); int[] i = Pair(1, 2); } T[] Pair(T a, T b) { return new T[] { a, b }; } 

尖括号允许您将类型传递给函数,方法与括号允许您传入值相同。 这里的“T”是类型参数的名称,就像上面的值参数“what”一样。 函数中出现的任何位置都将替换为您传入的实际类型(示例中为string和int)。

除此之外,你可以使用generics做一些东西,但这是基本的想法:generics允许你将类型传递给函数(和类),就像参数允许传递值一样。

generics基本上不需要将对象和对象转换为基类型。

例如,如果您想在列表中存储一组Foos。

您以前必须创建自己的FooList或将项目作为对象投射。

所有这些都需要时间和编译器。

使用generics所有你需要做的就是坐它列出它会检查你的类型并加速你的程序。 (没有拳击和拆箱)

假设你自己是一个算法,可以对任何可以成对比对的对象进行排序(扑克牌,CD,名片等等)。 您实际上并不关心提供这些具体对象的内容,您可以对它们进行比较。 因此,您将成为通用(此处“通用”用于广义术语,而不是C#意义上)算法。

.NET中的generics有助于促进这种特殊行为,不仅在算法(generics函数)方面,而且在generics类型(类,结构,委托,接口)方面。

只是添加其他人会告诉你的内容,更实际的是,尝试使用ArrayListSystem.Array对象做一些事情,然后尝试使用List ,你可以立即看到generics如何让你写得更具可读性代码并写得更快。

我很久以前在这里写过博客 。 我正在使用XML,我想要一个帮助器,它将获得一个XmlElement或一个XmlAttribute(基于XPath)并让我使用它。 这是一个很好的简单例子,我在现实世界中通过仿制药对C#来说相当新。