Hier gibt es bereits einige gute Antworten, die die Warnung und den Grund dafür erklären. Einige von diesen geben an, dass ein statisches Feld in einem generischen Typ im Allgemeinen ein Fehler ist .
Ich dachte, ich würde ein Beispiel hinzufügen, wie diese Funktion nützlich sein kann, dh ein Fall, in dem das Unterdrücken der R # -Warnung sinnvoll ist.
Stellen Sie sich vor, Sie haben eine Reihe von Entitätsklassen, die Sie serialisieren möchten, beispielsweise Xml. Sie können hierfür einen Serializer erstellen new XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
, müssen dann jedoch für jeden Typ einen eigenen Serializer erstellen. Mithilfe von Generika können Sie dies durch Folgendes ersetzen, das Sie in eine generische Klasse einfügen können, von der Entitäten abgeleitet werden können:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Da Sie wahrscheinlich nicht jedes Mal einen neuen Serializer generieren möchten, wenn Sie eine Instanz eines bestimmten Typs serialisieren müssen, können Sie Folgendes hinzufügen:
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);
}
}
Wenn diese Klasse NICHT generisch wäre, würde jede Instanz der Klasse dieselbe verwenden _typeSpecificSerializer
.
Da es jedoch generisch ist, wird eine Reihe von Instanzen mit demselben Typ für T
eine einzelne Instanz von _typeSpecificSerializer
(die für diesen bestimmten Typ erstellt wurde) gemeinsam nutzen, während Instanzen mit einem anderen Typ für T
unterschiedliche Instanzen von verwenden_typeSpecificSerializer
.
Ein Beispiel
Vorausgesetzt, die zwei Klassen, die sich erweitern 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; }
}
... lass sie uns benutzen:
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();
In diesem Fall wird unter der Haube, firstInst
und secondInst
werden Instanzen derselben Klasse (nämlich sein SerializableEntity<MyFirstEntity>
), und als solche werden sie eine Instanz teilen _typeSpecificSerializer
.
thirdInst
und fourthInst
sind Instanzen einer anderen Klasse ( SerializableEntity<OtherEntity>
), und so wird eine Instanz teilen von _typeSpecificSerializer
das ist verschieden von den anderen beiden.
Das heißt , Sie verschiedene Serializer-Instanzen für jede Ihrer Einheit erhalten Typen , während sie noch statisch im Rahmen des jeweiligen Ist - Typs (dh gemeinsam von den Instanzen , die von einem bestimmten Typ sind) zu halten.