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日查閱.