Здесь уже есть несколько хороших ответов, которые объясняют предупреждение и причину его возникновения. Некоторые из них указывают на то, что статическое поле общего типа обычно является ошибкой .
Я думал, что добавлю пример того, как эта функция может быть полезна, то есть случай, когда подавление предупреждения 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
.
Однако, поскольку он универсален, набор экземпляров с одинаковым типом for T
будет использовать один экземпляр _typeSpecificSerializer
(который будет создан для этого конкретного типа), а экземпляры с другим типом for T
будут использовать разные экземпляры _typeSpecificSerializer
.
Пример
Предусмотрено два класса, которые расширяются 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>
), и поэтому будут использовать экземпляр, _typeSpecificSerializer
который отличается от двух других.
Это означает, что вы получаете разные экземпляры сериализатора для каждого из ваших типов сущностей , сохраняя при этом их статичность в контексте каждого фактического типа (т. Е. Разделяемые между экземплярами определенного типа).