警告とその理由を説明するいくつかの良い答えがすでにここにあります。これらのいくつかは、一般的なタイプに静的フィールドがあるようなもので、一般的には間違いです。
この機能がどのように役立つか、つまりR#の警告を抑制することが理にかなっている例を追加したいと思いました。
Xmlのように、シリアル化するエンティティクラスのセットがあるとします。これを使用してシリアライザを作成できますnew XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
が、その場合、タイプごとに個別のシリアライザを作成する必要があります。ジェネリックを使用すると、それを次のものに置き換えることができます。これを、エンティティが派生できるジェネリッククラスに配置できます。
new XmlSerializerFactory().CreateSerializer(typeof(T))
特定のタイプのインスタンスをシリアル化する必要があるたびに新しいシリアライザを生成したくないので、次のように追加します。
public class SerializableEntity<T>
{
// ReSharper disable once StaticMemberInGenericType
private static XmlSerializer _typeSpecificSerializer;
private static XmlSerializer TypeSpecificSerializer
{
get
{
// Only create an instance the first time. In practice,
// that will mean once for each variation of T that is used,
// as each will cause a new class to be created.
if ((_typeSpecificSerializer == null))
{
_typeSpecificSerializer =
new XmlSerializerFactory().CreateSerializer(typeof(T));
}
return _typeSpecificSerializer;
}
}
public virtual string Serialize()
{
// .... prepare for serializing...
// Access _typeSpecificSerializer via the property,
// and call the Serialize method, which depends on
// the specific type T of "this":
TypeSpecificSerializer.Serialize(xmlWriter, this);
}
}
このクラスがジェネリックでない場合、クラスの各インスタンスは同じを使用し_typeSpecificSerializer
ます。
ただし、ジェネリックであるため、同じタイプのインスタンスのセットは(その特定のタイプ用に作成される)のT
単一のインスタンスを共有_typeSpecificSerializer
しますが、異なるタイプのT
インスタンスはの異なるインスタンスを使用します_typeSpecificSerializer
。
例
拡張する2つのクラスを提供SerializableEntity<T>
:
// Note that T is MyFirstEntity
public class MyFirstEntity : SerializableEntity<MyFirstEntity>
{
public string SomeValue { get; set; }
}
// Note that T is OtherEntity
public class OtherEntity : SerializableEntity<OtherEntity >
{
public int OtherValue { get; set; }
}
...それらを使用しましょう:
var firstInst = new MyFirstEntity{ SomeValue = "Foo" };
var secondInst = new MyFirstEntity{ SomeValue = "Bar" };
var thirdInst = new OtherEntity { OtherValue = 123 };
var fourthInst = new OtherEntity { OtherValue = 456 };
var xmlData1 = firstInst.Serialize();
var xmlData2 = secondInst.Serialize();
var xmlData3 = thirdInst.Serialize();
var xmlData4 = fourthInst.Serialize();
この場合、ボンネットの下、firstInst
及びsecondInst
(つまり同じクラスのインスタンスとなりSerializableEntity<MyFirstEntity>
)、そのようなものとして、それらはのインスタンスを共有します_typeSpecificSerializer
。
thirdInst
およびfourthInst
は異なるクラス(SerializableEntity<OtherEntity>
)のインスタンスなので、他の2つ_typeSpecificSerializer
とは異なるインスタンスを共有します。
つまり、エンティティタイプごとに異なるシリアライザーインスタンスを取得しながら、実際の各タイプのコンテキスト内でそれらを静的に保ちます(つまり、特定のタイプのインスタンス間で共有します)。