泛型是 C# 中在编译时确保类型安全的一种方式。
例子 - 泛型之前:
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
}
}
}
泛型让你可以像参数化值一样,将代码参数化为类型。这可能并不能完全解释清楚,所以让我们一步步来看:
想象一下你想要一个程序来打印“我喜欢兔子”。你可以写出以下代码:
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); }
static void Main()
{
string[] s = Pair("a", "b");
}
string[] Pair(string a, string b) { return new string[] { a, b }; }
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 }; }
泛型基本上消除了将对象转换为其基本类型的需要。
例如,如果您想在列表中存储一组Foos。
您以前必须创建自己的FooList或将项目强制转换为对象。
所有这些都需要花费您的时间和编译器。
使用泛型,您只需设置List,它会检查您的类型并加速程序。 (无装箱和拆箱)
ArrayList
或 System.Array
对象做一些事情,然后再尝试使用 List<T>
,你就可以立即看到泛型如何让你编写更易读的代码,并且更快地编写它。我很久以前写过一篇博客,链接在这里。当时我正在处理XML,我想要一个帮助类,可以根据XPath获取一个XmlElement或者XmlAttribute,并让我方便地操作它。这是一个非常好的简单示例,当时泛型在C#中还比较新。