C Sharp/Generics
< C Sharp
泛型(Generics)是C# 2.0引入的特性。支持了类型作为参数。最常见的使用情形是创建collection类。泛型极大化了代码重用、类型安全和性能。[1]
泛型类
编辑如果想创建一个支持各种类型的容器,如下例:
public class SomeObjectContainer
{
private object _obj;
public SomeObjectContainer(object obj)
{
this._obj = obj;
}
public object GetObject()
{
return this._obj;
}
}
使用该容器:
class Program
{
static void Main(string[] args)
{
SomeObjectContainer container = new SomeObjectContainer(25);
SomeObjectContainer container2 = new SomeObjectContainer(5);
Console.WriteLine((int) container.GetObject() + (int) container2.GetObject());
Console.ReadKey(); // wait for user to press any key, so we could see results
}
}
可见看到用值类型的值初始化该容器,需要“自动装箱”(autoboxing),使用时还需要类型转化为整数。这些都是性能惩罚。使用泛型,不仅可以优化性能,还实现了类型安全。如下例:
public class GenericObjectContainer<T>
{
private T _obj;
public GenericObjectContainer(T obj)
{
this._obj = obj;
}
public T getObject()
{
return this._obj;
}
}
使用这个泛型类:
class Program
{
static void Main(string[] args)
{
GenericObjectContainer<int> container = new GenericObjectContainer<int>(25);
GenericObjectContainer<int> container2 = new GenericObjectContainer<int>(5);
Console.WriteLine(container.getObject() + container2.getObject());
Console.ReadKey(); // wait for user to press any key, so we could see results
}
}
泛型接口
编辑public interface IContainer<T>
{
T GetObject();
void SetObject(T value);
}
public class StringContainer : IContainer<string>
{
private string _str;
public string GetObject()
{
return _str;
}
public void SetObject(string value)
{
_str = value;
}
}
public class FileWithString : IContainer<string>
{
...
}
class Program
{
static void Main(string[] args)
{
IContainer<string> container = new StringContainer();
container.SetObject("test");
Console.WriteLine(container.GetObject());
container = new FileWithString();
container.SetObject("another test");
Console.WriteLine(container.GetObject());
Console.ReadKey();
}
}
List<T>
类和LinkedList<T>
类,都声明在System.Collections.Generic
命名空间,实现了IEnumerable<T>
接口。List<T>
的一个构造函数基于实现了IEnumerable<T>
接口的对象构造一个List,如下例:
LinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddLast(1);
linkedList.AddLast(2);
linkedList.AddLast(3);
// linkedList now contains 1, 2 and 3.
List<int> list = new List<int>(linkedList);
// now list contains 1, 2 and 3 as well!
泛型方法
编辑using System;
using System.Collections.Generic;
public static bool ArrayContains<T>(T[] array, T element)
{
foreach (T e in array)
{
if (e.Equals(element))
{
return true;
}
}
return false;
}
可用于搜索任何类型的数组:
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
string[] strArray = { "string one", "string two", "string three" };
int[] intArray = { 123, 456, 789 };
Console.WriteLine(ArrayContains<string>(strArray, "string one")); // True
Console.WriteLine(ArrayContains<int>(intArray, 135)); // False
}
}
类型约束
编辑可明确指出泛型的类型参数的约束条件。如下例:
public class MyClass<T, U, V, W>
where T : class, // T should be a reference type (array, class, delegate, interface)
new() // T should have a public constructor with no parameters
where U : struct // U should be a value type (byte, double, float, int, long, struct, uint, etc.)
where V : MyOtherClass, // V should be derived from MyOtherClass
IEnumerable<U> // V should implement IEnumerable<U>
where W : T, // W should be derived from T
IDisposable // W should implement IDisposable
{
...
}
参考文献
编辑- ↑ Generics (C# Programming Guide).msdn.于2011年8月9日查阅.