Sudah ada beberapa jawaban bagus di sini, yang menjelaskan peringatan dan alasannya. Beberapa dari keadaan ini seperti memiliki medan statis dalam tipe generik umumnya kesalahan .
Saya pikir saya akan menambahkan contoh bagaimana fitur ini dapat berguna, yaitu kasus di mana menekan peringatan R # masuk akal.
Bayangkan Anda memiliki seperangkat kelas entitas yang ingin Anda buat bersambung, katakanlah ke Xml. Anda dapat membuat serializer untuk penggunaan ini new XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
, tetapi kemudian Anda harus membuat serializer terpisah untuk setiap jenis. Menggunakan generik, Anda bisa menggantinya dengan yang berikut ini, yang bisa Anda tempatkan di kelas generik tempat entitas dapat berasal:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Karena Anda mungkin tidak ingin membuat serializer baru setiap kali Anda perlu membuat cerita bersambung dari jenis tertentu, Anda dapat menambahkan ini:
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);
}
}
Jika kelas ini TIDAK generik, maka setiap instance dari kelas akan menggunakan yang sama _typeSpecificSerializer
.
Karena IS generik, satu set instance dengan tipe yang sama untuk T
akan membagikan satu instance _typeSpecificSerializer
(yang akan dibuat untuk tipe spesifik itu), sedangkan instance dengan tipe berbeda untuk T
akan menggunakan instance berbeda dari _typeSpecificSerializer
.
Sebuah contoh
Asalkan dua kelas yang memperpanjang 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; }
}
... mari kita gunakan:
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();
Dalam hal ini, di bawah tenda, firstInst
dan secondInst
akan menjadi instance dari kelas yang sama (yaitu SerializableEntity<MyFirstEntity>
), dan dengan demikian, mereka akan berbagi instance dari _typeSpecificSerializer
.
thirdInst
dan fourthInst
merupakan instance dari kelas yang berbeda ( SerializableEntity<OtherEntity>
), dan juga akan berbagi contoh _typeSpecificSerializer
yang berbeda dari dua lainnya.
Ini berarti Anda mendapatkan instans serializer yang berbeda untuk masing-masing jenis entitas Anda , sambil tetap membuatnya statis dalam konteks masing-masing jenis aktual (yaitu, dibagikan di antara instance yang dari jenis tertentu).