私は値型/参照型制約が有用であることを示す簡単な例を探しています。値型/参照型制約はいつ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:class
の場合は、Tのas
演算子を使用できます。
TがT:struct
の場合、Tとnull
とを比較することは禁じられています。
T:class
を省略すると、Tが値型の場合でもTとnullを比較できます。
[注:この記事を正しく編集するには、この記事を数回編集する必要がありました。少なくとも今は正しいと思います。]
"T:class"は、指定されたジェネリック型を強制的に値ではなくクラスにします。これは、そうでない場合は強制力ではないかもしれませんあなたのジェネリック型Tの不変を強制
class ObjectList<T> where T : class {
...
}
class SomeObject { ... }
ObjectList<int> invalidList = new ObjectList<int>(); //compiler error
ObjectList<SomeObject> someObjectList = new ObjectList<SomeObject>(); //this works
:たとえば、私たちはクラスではなく、値に指定されたジェネリック型を必要とObjectListクラスを作ることができます。 "T:struct"は同じように動作します。この構文を使用して、タイプTがクラスであることだけでなく、それがインターフェイスに一致することを強制することもできます。私がこれを取りに行ったコードサンプルは、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()"制約に依存し、class/struct制約には依存しないと考えましたか?また、私はC#のマーシャリングとメモリの固定に精通していませんが、おそらくコード例を提供できますか? – Oak
それはすべて特定の詳細に依存します。私の場合は、既存のバイトセットを構造体に変換する必要がありました。しかし、新しいインスタンスの作成は、具体的にはnew()制約に依存します。私はこれを反映するために私の応答を編集しました。 –
ありがとうございましたしかし、私はジェネリック制約のセマンティクスを知っています - 私が求めているのは、struct/class制約が有用な例です。 – Oak