Có một số câu trả lời tốt ở đây đã giải thích cảnh báo và lý do cho nó. Một số trong những trạng thái này giống như có một trường tĩnh trong một loại chung thường là một lỗi .
Tôi nghĩ rằng tôi đã thêm một ví dụ về cách tính năng này có thể hữu ích, ví dụ như trường hợp triệt tiêu R # -warning có ý nghĩa.
Hãy tưởng tượng bạn có một tập hợp các lớp thực thể mà bạn muốn tuần tự hóa, nói với Xml. Bạn có thể tạo một serializer cho việc này bằng cách sử dụng new XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
, nhưng sau đó bạn sẽ phải tạo một serializer riêng cho từng loại. Sử dụng generic, bạn có thể thay thế bằng cái sau, cái mà bạn có thể đặt trong một lớp chung mà các thực thể có thể xuất phát từ:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Vì có thể bạn không muốn tạo một bộ nối tiếp mới mỗi lần bạn cần tuần tự hóa một thể hiện của một loại cụ thể, bạn có thể thêm điều này:
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);
}
}
Nếu lớp này KHÔNG chung chung, thì mỗi phiên bản của lớp sẽ sử dụng như nhau _typeSpecificSerializer
.
Tuy nhiên, vì nó chung chung, một tập hợp các thể hiện có cùng loại T
sẽ chia sẻ một thể hiện duy nhất _typeSpecificSerializer
(sẽ được tạo cho loại cụ thể đó), trong khi các phiên bản có loại khác T
sẽ sử dụng các phiên bản khác nhau _typeSpecificSerializer
.
Một ví dụ
Cung cấp hai lớp mở rộng 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; }
}
... Hãy sử dụng chúng:
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();
Trong trường hợp này, dưới mui xe, firstInst
và secondInst
sẽ là các thể hiện của cùng một lớp (cụ thể SerializableEntity<MyFirstEntity>
), và như vậy, chúng sẽ chia sẻ một thể hiện của _typeSpecificSerializer
.
thirdInst
và fourthInst
là các thể hiện của một lớp khác ( SerializableEntity<OtherEntity>
) và do đó sẽ chia sẻ một thể _typeSpecificSerializer
hiện khác với hai lớp kia.
Điều này có nghĩa là bạn nhận được các phiên bản tuần tự hóa khác nhau cho từng loại thực thể của mình , trong khi vẫn giữ chúng tĩnh trong ngữ cảnh của từng loại thực tế (nghĩa là được chia sẻ giữa các phiên bản thuộc loại cụ thể).