开发者

When is a value type / reference type constraint useful in C#?

开发者 https://www.devze.com 2023-02-06 00:44 出处:网络
I\'m looking for simple examples that demonstrate when the value type / reference type 开发者_运维问答constraints are useful.

I'm looking for simple examples that demonstrate when the value type / reference type 开发者_运维问答constraints are useful.

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

I remember seeing some very nice examples in the past but I just can't find them.


It allows you to use as operator on T if it is T:class.

It forbids you to compare T with null if T is T:struct.

Note that if you omit T:class then you can compare T to null even when T is a value type.

[Note: I needed to edit this post a few times before it got correct. At least I hope it is now correct.]


The primary usefulness that I've found in it lies with Marshalling and pinning the object in memory.

For example, I do a lot of work with internal structures that can't be auto-converted, or are sent down the wire as a byte stream, so I wrote this helper:

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 : class" will force the generic type specified to be a class, not a value. For example, we can make up an ObjectList class that requires the generic type specified to be a class, not a value:

class ObjectList<T> where T : class {
  ...
}

class SomeObject { ... }

ObjectList<int> invalidList = new ObjectList<int>();  //compiler error

ObjectList<SomeObject> someObjectList = new ObjectList<SomeObject>(); //this works

This forces an invariant on your generic type T that otherwise might not be enforceable. "T : struct" would work the same way. Note that you can also use this construct to enforce not only that the type T is a class, but also that it matches an interface. The code sample I took this from also has

class MyList<T> where T : class, IEntity { ... }

which forces T to be a class AND also be an IEntity.

0

精彩评论

暂无评论...
验证码 换一张
取 消