Aquí hay varias buenas respuestas que explican la advertencia y el motivo. Varios de estos estados, como tener un campo estático en un tipo genérico, generalmente son un error .
Pensé que agregaría un ejemplo de cómo esta característica puede ser útil, es decir, un caso en el que suprimir la advertencia R # tiene sentido.
Imagine que tiene un conjunto de clases de entidad que desea serializar, digamos a Xml. Puede crear un serializador para este uso new XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
, pero luego tendrá que crear un serializador separado para cada tipo. Usando genéricos, puede reemplazar eso con lo siguiente, que puede colocar en una clase genérica de la cual las entidades pueden derivar:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Dado que probablemente no desee generar un nuevo serializador cada vez que necesite serializar una instancia de un tipo en particular, puede agregar esto:
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);
}
}
Si esta clase NO fuera genérica, entonces cada instancia de la clase usaría lo mismo _typeSpecificSerializer
.
Sin embargo, dado que ES genérico, un conjunto de instancias con el mismo tipo para T
compartirá una única instancia de _typeSpecificSerializer
(que se habrá creado para ese tipo específico), mientras que las instancias con un tipo diferente para T
utilizarán diferentes instancias de _typeSpecificSerializer
.
Un ejemplo
Proporcionaron las dos clases que se extienden 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; }
}
... usémoslos:
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();
En este caso, bajo el capó, firstInst
y secondInst
serán instancias de la misma clase (a saber SerializableEntity<MyFirstEntity>
), y como tal, compartirán una instancia de _typeSpecificSerializer
.
thirdInst
y fourthInst
son instancias de una clase diferente ( SerializableEntity<OtherEntity>
), y así se comparten una instancia de _typeSpecificSerializer
que es diferente de los otros dos.
Esto significa que obtiene diferentes instancias de serializador para cada uno de sus tipos de entidad , mientras las mantiene estáticas dentro del contexto de cada tipo real (es decir, compartidas entre instancias que son de un tipo específico).