什么时候在C#中有用的值类型/引用类型约束?

时间:2011-01-19 09:46:18

标签: c# generics constraints

我正在寻找简单的示例来演示值类型/引用类型约束何时有用。

... where T : struct  // when is this useful?
... where T : class   // and what about this?

我记得过去看过一些非常好的例子,但我找不到它们。

3 个答案:

答案 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。