什么是“<>” C#中的语法

时间:2008-09-30 21:51:49

标签: c# .net

我一直在学习C#的基础知识,但没有得到很好的解释:

var l = new List<string>();

我不知道<string>正在做什么,或者是List正在做什么。我还看到对象被抛出< >标签。

有人可以用例子向我解释这个吗?

7 个答案:

答案 0 :(得分:24)

这是C#的通用语法。

基本概念是它允许您使用Type占位符并在编译时替换实际的实际类型。

例如,旧的方式:

ArrayList foos = new Arraylist();
foos.Add("Test");

通过使ArrayList存储System.Objects列表(所有.NET的基本类型)来工作。

因此,当从列表中添加或检索对象时,CLR必须将其强制转换为对象,基本上真正发生的是:

foos.Add("Test" as System.Object);
string s = foos[1] as String.

这会导致演员阵容的性能下降,而且它也不安全,因为我可以这样做:

ArrayList listOfStrings = new ArrayList();
listOfStrings.Add(1);
listOfStrings.Add("Test");

这将编译得很好,即使我在listOfStrings中放了一个整数。

泛型改变了所有这一切,现在使用泛型我可以声明我的集合所期望的类型:

List<int> listOfIntegers = new List<int>();
List<String> listOfStrings = new List<String>();

listOfIntegers.add(1);

// Compile time error.
listOfIntegers.add("test");

这提供了编译时类型的安全性,并避免了昂贵的铸造操作。

您利用此方法非常简单,但有一些高级边缘情况。基本概念是通过使用类型占位符使您的类类型不可知,例如,如果我想创建一个通用的“添加两件事”类。

public class Adder<T>
{
   public T AddTwoThings(T t1, T t2)
   {
       return t1 + t2;
   }
}

Adder<String> stringAdder = new Adder<String>();
Console.Writeline(stringAdder.AddTwoThings("Test,"123"));

Adder<int> intAdder = new Adder<int>();
Console.Writeline(intAdder.AddTwoThings(2,2));

有关泛型的更详细解释,我不能通过C#推荐CLR一书。

答案 1 :(得分:5)

它是泛型 - 它是一种类型参数化的形式。在你的例子中,它引用了一个字符串列表 - 列表只会包含字符串:编译器会对它进行处理(相当多),就好像API文档中提到的“T”实际上都是“字符串”一样。所以,你只能添加字符串,如果使用索引器,则不需要转换为字符串等。

老实说,在网上论坛上提供泛型详细报道几乎是不可能的。 (在深度的C#中,我花了近50页来讨论泛型。)然而,凭借该功能的名称,您应该处于更好的位置以了解更多信息。 MSDN "Introduction to C# Generics"可能是一个很好的起点。

在SO上询问关于泛型的具体问题可能会产生良好的结果 - 我只是认为在一个问题/答案中不能真正涵盖它。

答案 2 :(得分:1)

这是.NET Generics。 &lt;中的类型&GT;表示列表中包含的元素类型。

使用ArrayList你必须将元素转换为...

int x = (int)myArrayList[4];

使用List可以避免该步骤,因为编译器已经知道了类型。

int x = myList[4];

.NET 2.0及更高版本中提供了泛型。

答案 3 :(得分:1)

这些是泛型。您正在创建一个仅包含字符串的List。你也可以说

List<int>

并获取仅包含int的列表。

泛型是一个很大的话题,对于这里的单个答案来说太大了。

答案 4 :(得分:1)

这些被称为泛型(特别是List是泛型类)。

从MSDN阅读

答案 5 :(得分:1)

这是仿制药。常规List存储Object类型的项。这需要在类型之间进行转换这也允许您将任何类型的项目存储在列表的一个实例中。当您迭代该列表中的项目时,您无法确定它们是否都属于某种类型(至少在没有强制转换每个项目的情况下)。例如,假设你创建一个这样的列表:

List listOfStrings = new List();

没有什么能阻止某人做这样的事情:

listOfStrings.add(6); //Not a string

通用列表允许您指定强类型列表。

List<string> listOfStrings = new List<string>();
listOfStrings.add("my name"); //OK
listofStrings.add(6); //Throws a compiler error

这里有一个更全面的例子Generics

答案 6 :(得分:0)

&LT; &GT;是为了泛型。在您的具体示例中,这意味着List是一个字符串列表,而不是一个整数列表。

泛型用于允许类型通用。它在集合中使用ALOT来允许它们采用不同的类型,这样它们就可以像普通数组一样运行,并且仍然捕获在编译时分配的无效类型。基本上它允许类说“我需要与某个特定类型T相关联,但我不想硬编码该类型的确切内容,并让用户选择它。”。例如,一个简单的数组可能类似于:

public class MyArray<T> {
    private T[] _list;

    public MyArray() : this.MyArray(10);
    public MyArray(int capacity)
    { _list = new T[capacity]; }

    T this[int index] {
        get { return _list[index]; }
        set { _list[index] = value; }
    }
}

这里,我们有一个类型为T的私有列表,可以像普通数组一样使用我们的类来访问。我们不关心它是什么类型,它对我们的代码无关紧要。但是任何使用该类的人都可以使用它,比如MyArray<string>来创建一个字符串列表,而其他人可能会将它用作MyArray<bool>并创建一个标记列表。