Тут уже є кілька хороших відповідей, які пояснюють попередження та причину цього. Кілька з них констатують щось на зразок наявності статичного поля в загальному типі, як правило, помилка .
Я думав, що додам приклад того, як ця функція може бути корисною, тобто випадок, коли придушення попередження 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 .
Приклад
Надано два класи, які розширюються 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буде іншим від двох інших.
Це означає, що ви отримуєте різні екземпляри серіалізатора для кожного з типів вашої сутності , зберігаючи їх статичними в контексті кожного фактичного типу (тобто поділяються між екземплярами певного типу).