答案 0 :(得分:4)
泛型是一种在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.
}
}
}
示例 - 后泛型:
class ClientCode
{
public static void Main()
{
//create a list of person
List<Person> personList = new List<Person>();
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
}
}
}
答案 1 :(得分:3)
泛型允许您以与参数允许您对值进行参数化的方式相同的方式对代码进行参数化。这可能并不能解释很多,所以让我们一步一步地完成它:
想象一下,你想要一个程序来打印“我喜欢兔子”。你写这个:
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"); }
您注意到您的两个功能几乎完全相同。您希望重用相同的函数,但为您喜欢的内容提供不同的值:
static void Main()
{
ILike("bunnies");
ILike("cheese");
}
void ILike(string what) { Console.WriteLine("I like " + what); }
这是函数参数的用途:它们允许您重用具有不同值的相同代码。
泛型就是这样,但不是传入不同的值,而是传递 types 。假设你有代码需要将两个字符串捆绑到一个数组中:
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 }; }
就像以前一样,我们可以看到那里有一堆冗余。我们需要的是一个返回一对无论的函数和一种传入我们想要的一对的类型的函数。这是泛型的用途:
static void Main()
{
string[] s = Pair<string>("a", "b");
int[] i = Pair<int>(1, 2);
}
T[] Pair<T>(T a, T b) { return new T[] { a, b }; }
尖括号允许您将类型传递给函数,就像括号允许您传入值一样。这里的“T”是类型参数的名称,就像上面的值参数“what”一样。函数中出现的任何位置都将替换为您传入的实际类型(示例中为字符串和整数)。
除此之外,你可以使用泛型做一些事情,但这是基本的想法:泛型允许你将类型传递给函数(和类),就像参数允许你传入值一样。
答案 2 :(得分:1)
泛型基本上不需要将对象和对象转换为基类型。
e.g。如果你想在List中存储一组Foos。
您以前必须创建自己的FooList或将项目转换为对象。
所有这些都需要时间和编译器。
使用泛型所有你需要做的就是坐它列出它会检查你的类型并加速你的程序。 (没有装箱和拆箱)
答案 3 :(得分:0)
假设您自己是一种算法,它可以对任何可以成对比对的对象进行排序(游戏卡,CD,名片等等)。您实际上并不感兴趣的是提供了这些具体对象,您可以对它们进行比较。因此,您将成为通用(此处“通用”用于广义术语,而不是C#意义上的算法)。
.NET中的泛型有助于促进这种特殊行为,不仅在算法(泛型函数)方面,而且在泛型类型(类,结构,委托,接口)方面。
答案 4 :(得分:0)
只是添加其他人会告诉你的内容,更实际的是,尝试使用ArrayList
或System.Array
对象做一些事情,然后尝试使用List<T>
进行操作,你可以立即看看泛型如何让你编写更易读的代码并更快地编写代码。
答案 5 :(得分:0)
I blogged about it a long time ago, here。我正在使用XML,我想要一个帮助器,它将获得一个XmlElement或一个XmlAttribute(基于XPath)并让我使用它。这是一个很好的简单例子,我在现实世界中经历了泛型对C#来说相当新的时候。