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