我是C#的新手,并直接潜入修改我收到的项目的一些代码。但是,我一直看到这样的代码:
class SampleCollection<T>
我无法理解
<T>
表示也不称之为。
如果有人愿意帮我说出这个概念的名称,我可以在线搜索。但是,到目前为止我还是一无所知。
答案 0 :(得分:93)
泛型类型参数允许您在编译时为方法指定任意类型T,而无需在方法或类声明中指定具体类型。
例如:
public T[] Reverse<T>(T[] array)
{
var result = new T[array.Length];
int j=0;
for(int i=array.Length; i>= 0; i--)
{
result[j] = array[i];
j++;
}
return result;
}
反转数组中的元素。这里的关键点是数组元素可以是任何类型,函数仍然可以工作。您在方法调用中指定类型;类型安全仍然有保证。
所以,要反转一个字符串数组:
string[] array = new string[] { "1", "2", "3", "4", "5" };
var result = reverse(array);
将在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; i >= 0; i--)
{
result[j] = array[i];
j++;
}
return result;
}
编译器看到array
包含字符串,因此它返回一个字符串数组。类型string
代替T
类型参数。
通用类型参数也可用于创建泛型类。在您提供SampleCollection<T>
的示例中,T
是任意类型的占位符;这意味着SampleCollection
可以表示对象的集合,您在创建集合时指定的类型。
所以:
var collection = new SampleCollection<string>();
创建一个可以保存字符串的集合。上面说明的Reverse
方法可以用来反转集合的成员。
答案 1 :(得分:19)
这是一个通用类型参数see Generics documentation。
T
不是保留关键字。 T
, 或任何给定名称 ,表示类型参数。检查以下方法(仅作为一个简单示例)。
T GetDefault<T>()
{
return default(T);
}
请注意,返回类型为T
。使用此方法,您可以通过调用方法获取任何类型的默认值:
GetDefault<int>(); // 0
GetDefault<string>(); // null
GetDefault<DateTime>(); // 01/01/0001 00:00:00
GetDefault<TimeSpan>(); // 00:00:00
.NET在集合中使用泛型,...示例:
List<int> integerList = new List<int>();
这样,您将拥有一个只接受整数的列表,因为该类是使用类型T
实现的,在本例中是int
,并且添加元素的方法写为:
public class List<T> : ...
{
public void Add(T item);
}
有关泛型的更多信息。
您可以限制类型T
的范围。
以下示例仅允许您使用类类型调用方法:
void Foo<T>(T item) where T: class
{
}
以下示例仅允许您使用Circle
或从其继承的类型调用方法。
void Foo<T>(T item) where T: Circle
{
}
并且new()
表示如果它具有无参数构造函数,则可以创建T
的实例。在以下示例中,T
将被视为Circle
,您将获得智能感知......
void Foo<T>(T item) where T: Circle, new()
{
T newCircle = new T();
}
由于T
是一个类型参数,您可以从中获取对象Type
。使用Type
,您可以使用反射...
void Foo<T>(T item) where T: class
{
Type type = typeof(T);
}
作为一个更复杂的示例,请检查ToDictionary
或任何其他Linq方法的签名。
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
没有T
,但有TKey
和TSource
。建议您始终使用前缀T
命名类型参数,如上所示。
如果您愿意,可以为TSomethingFoo
命名。
答案 2 :(得分: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];
}
}
在您的代码中,您可以执行以下操作:
MyArray<int> = new MyArray<int>();
在这种情况下,T[] array
的工作方式与int[] array
相同,public T GetItem
的工作方式与public int GetItem
相同。