我正在尋找簡單的示例,演示何時值類型/引用類型約束是有用的。什麼時候在C#中有用的值類型/引用類型約束?
... where T : struct // when is this useful?
... where T : class // and what about this?
我記得過去看過一些很好的例子,但我找不到它們。
我正在尋找簡單的示例,演示何時值類型/引用類型約束是有用的。什麼時候在C#中有用的值類型/引用類型約束?
... where T : struct // when is this useful?
... where T : class // and what about this?
我記得過去看過一些很好的例子,但我找不到它們。
它允許您在T上使用as
運算符,如果它是T:class
。
如果T爲T:struct
,則禁止您將T與null
進行比較。
請注意,如果您省略了T:class
,那麼即使T是值類型,也可以將T與空值進行比較。
[注意:我需要編輯這個帖子幾次才能得到正確的。至少我希望現在是正確的。]
「T:class」將強制指定的泛型類型爲類,而不是值。例如,我們可以彌補,需要指定爲一類,而不是一個值泛型類型的鏈表類類:
class ObjectList<T> where T : class {
...
}
class SomeObject { ... }
ObjectList<int> invalidList = new ObjectList<int>(); //compiler error
ObjectList<SomeObject> someObjectList = new ObjectList<SomeObject>(); //this works
這迫使你的泛型類型T的不變,否則可能無法執行。 「T:struct」將以同樣的方式工作。請注意,您也可以使用此構造來強制執行,不僅T類型是類,而且它與接口匹配。我從這個代碼示例也有這
class MyList<T> where T : class, IEntity { ... }
這迫使T是一個類,也是一個IEntity。
我發現它的主要用處在於編組並將對象固定在內存中。
例如,我做了很多與內部結構不能被自動轉換,或發送沿着電線作爲字節流的工作,所以我寫了這個幫手:
public static T PinAndCast<T>(this Array o) where T : struct
{
var handle = System.Runtime.InteropServices.GCHandle.Alloc(o, GCHandleType.Pinned);
T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return result;
}
我認爲創建新實例取決於「T:new()」約束,而不是類/結構約束?另外,我並不是很熟悉C#中的編組和內存鎖定,您能否提供一個代碼示例? – Oak 2011-01-19 10:36:38
謝謝,但我意識到泛型約束的語義 - 我要求的是結構/類約束* *有用*的示例。 – Oak 2011-01-19 10:34:17