我正在寻找简单的示例来演示值类型/引用类型约束何时有用。
... where T : struct // when is this useful?
... where T : class // and what about this?
我记得过去看过一些非常好的例子,但我找不到它们。
答案 0 :(得分:11)
如果是as
,则允许您在T上使用T:class
运算符。
如果T为null
,则禁止您将T与T:struct
进行比较。
请注意,如果省略T:class
,则即使T是值类型,也可以将T与null进行比较。
[注意:我需要在正确之前编辑此帖子几次。至少我希望现在是正确的。]
答案 1 :(得分:1)
我发现它的主要用处在于编组并将对象固定在内存中。
例如,我对内部结构进行了大量工作,这些内部结构无法自动转换,或者作为字节流在线路上发送,所以我写了这个帮助器:
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;
}
答案 2 :(得分:-1)
“T:class”将强制指定的泛型类型为类,而不是值。例如,我们可以组成一个ObjectList类,它要求指定的泛型类型是一个类,而不是一个值:
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。