Ci sono già molte buone risposte che spiegano l'avvertimento e il motivo di ciò. Molti di questi affermano qualcosa come avere un campo statico in un tipo generico generalmente un errore .
Ho pensato di aggiungere un esempio di come questa funzionalità possa essere utile, ad esempio un caso in cui sopprimere la segnalazione R # ha senso.
Immagina di avere una serie di classi di entità che vuoi serializzare, diciamo a Xml. Puoi creare un serializzatore per questo usando new XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
, ma poi dovrai creare un serializzatore separato per ogni tipo. Usando generics, puoi sostituirlo con il seguente, che puoi inserire in una classe generica da cui le entità possono derivare:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Poiché probabilmente non vuoi generare un nuovo serializzatore ogni volta che devi serializzare un'istanza di un tipo particolare, potresti aggiungere questo:
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);
}
}
Se questa classe NON fosse generica, ogni istanza della classe userebbe la stessa _typeSpecificSerializer
.
Poiché è generico, tuttavia, una serie di istanze con lo stesso tipo per T
condividerà una singola istanza di _typeSpecificSerializer
(che sarà stata creata per quel tipo specifico), mentre le istanze con un tipo T
diverso utilizzeranno istanze diverse di_typeSpecificSerializer
.
Un esempio
Fornito le due classi che si estendono 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; }
}
... usiamoli:
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 questo caso, sotto il cofano, firstInst
e secondInst
saranno istanze della stessa classe (vale a dire SerializableEntity<MyFirstEntity>
), e come tali, condivideranno un'istanza di _typeSpecificSerializer
.
thirdInst
e fourthInst
sono istanze di una classe diversa ( SerializableEntity<OtherEntity>
), e quindi condivideranno un'istanza _typeSpecificSerializer
che è diversa dalle altre due.
Ciò significa che ottieni istanze serializzatore diverse per ciascuno dei tuoi tipi di entità , pur mantenendole statiche nel contesto di ciascun tipo effettivo (ovvero, condivise tra istanze di un tipo specifico).