<T>在C#中表示什么

Yas*_*sai 82 .net c# generics

我是C#的新手,并直接潜入修改我收到的项目的一些代码.但是,我一直看到这样的代码:

class SampleCollection<T>
Run Code Online (Sandbox Code Playgroud)

而我无法弄清楚是什么

<T> 
Run Code Online (Sandbox Code Playgroud)

意味着什么也不称之为.

如果有人愿意帮我说出这个概念的名称,我可以在线搜索.但是,到目前为止我还是一无所知.

Rob*_*vey 102

它是通用类型参数.

泛型类型参数允许您在编译时为方法指定任意类型T,而无需在方法或类声明中指定具体类型.

例如:

public T[] Reverse<T>(T[] array)
{
    var result = new T[array.Length];
    int j=0;
    for(int i=array.Length - 1; i>= 0; i--)
    {
        result[j] = array[i];
        j++;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

反转数组中的元素.这里的关键点是数组元素可以是任何类型,函数仍然可以工作.您在方法调用中指定类型; 类型安全仍然有保证.

所以,要反转一个字符串数组:

string[] array = new string[] { "1", "2", "3", "4", "5" };
var result = reverse(array);
Run Code Online (Sandbox Code Playgroud)

会产生一个字符串数组result{ "5", "4", "3", "2", "1" }

这与您调用如下所示的普通(非泛型)方法具有相同的效果:

public string[] Reverse(string[] array)
{
    var result = new string[array.Length];
    int j=0;
    for(int i=array.Length - 1; i >= 0; i--)
    {
        result[j] = array[i];
        j++;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

编译器看到它array包含字符串,因此它返回一个字符串数组.Type string替换Ttype参数.


通用类型参数也可用于创建泛型类.在你给出a的例子中SampleCollection<T>,T是一个任意类型的占位符; 它表示SampleCollection可以表示对象的集合,对象的类型是您在创建集合时指定的类型.

所以:

var collection = new SampleCollection<string>();
Run Code Online (Sandbox Code Playgroud)

创建一个可以保存字符串的集合.Reverse上面说明的方法以稍微不同的形式可用于反转集合的成员.

  • 是的,尽管您可以使用反射在运行时使用类型参数实例化泛型类,但是在使用泛型在运行时指定类型时会很困惑,正常使用时在编译时指定一个类型. (2认同)

Bru*_*oLM 24

它是泛型类型参数,请参阅泛型文档.

T不是保留关键字.T,或任何给定的名称,是指类型参数.检查以下方法(仅作为一个简单示例).

T GetDefault<T>()
{
    return default(T);
}
Run Code Online (Sandbox Code Playgroud)

请注意,返回类型是T.使用此方法,您可以通过调用方法获取任何类型的默认值:

GetDefault<int>(); // 0
GetDefault<string>(); // null
GetDefault<DateTime>(); // 01/01/0001 00:00:00
GetDefault<TimeSpan>(); // 00:00:00
Run Code Online (Sandbox Code Playgroud)

.NET在集合中使用泛型,...示例:

List<int> integerList = new List<int>();
Run Code Online (Sandbox Code Playgroud)

这样,您将拥有一个只接受整数的列表,因为T在这种情况下int,类是使用类型进行实例化的,并且添加元素的方法写为:

public class List<T> : ...
{
    public void Add(T item);
}
Run Code Online (Sandbox Code Playgroud)

有关泛型的更多信息.

您可以限制类型的范围T.

以下示例仅允许您使用类类型调用方法:

void Foo<T>(T item) where T: class
{
}
Run Code Online (Sandbox Code Playgroud)

以下示例仅允许您使用从中Circle继承或继承的类型来调用方法.

void Foo<T>(T item) where T: Circle
{
}
Run Code Online (Sandbox Code Playgroud)

还有new()就是说你可以创建一个T如果它有一个无参数构造函数的实例.在下面的例子T将被视为Circle,你得到intellisense ...

void Foo<T>(T item) where T: Circle, new()
{
    T newCircle = new T();
}
Run Code Online (Sandbox Code Playgroud)

作为T类型参数,您可以从中获取对象Type.随Type你可以使用反射......

void Foo<T>(T item) where T: class
{
    Type type = typeof(T);
}
Run Code Online (Sandbox Code Playgroud)

作为一个更复杂的示例,请检查签名ToDictionary或任何其他Linq方法.

public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
Run Code Online (Sandbox Code Playgroud)

没有T,但有TKeyTSource.建议您始终使用前缀命名类型参数,T如上所示.

你可以TSomethingFoo根据需要命名.


Ken*_*rey 8

此功能称为泛型.http://msdn.microsoft.com/en-us/library/512aeb7t(v=vs.100).aspx

一个例子是制作特定类型的项目的集合.

class MyArray<T>
{
    T[] array = new T[10];

    public T GetItem(int index)
    {
        return array[index];
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的代码中,您可以执行以下操作:

MyArray<int> = new MyArray<int>();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,T[] array会工作int[] array,public T GetItem并将工作public int GetItem.