Burada zaten uyarıyı ve nedenini açıklayan birkaç iyi cevap var. Bunların birçoğu jenerik tipte statik bir alana sahip olmak gibi bir şeyi genellikle bir hata olarak belirtir .
Bu özelliğin nasıl yararlı olabileceğine bir örnek ekleyeceğimi düşündüm, yani R # uyarısının bastırılmasının mantıklı olduğu bir durum.
Serileştirmek istediğiniz bir dizi varlık sınıfınız olduğunu düşünün, örneğin Xml. Bunu kullanarak bir serileştirici oluşturabilirsiniz new XmlSerializerFactory().CreateSerializer(typeof(SomeClass))
, ancak daha sonra her tür için ayrı bir serileştirici oluşturmanız gerekir. Jenerikler kullanarak, bunu varlıkların türetebileceği genel bir sınıfa yerleştirebileceğiniz aşağıdakilerle değiştirebilirsiniz:
new XmlSerializerFactory().CreateSerializer(typeof(T))
Muhtemelen belirli bir türdeki bir örneği her serileştirmeniz gerektiğinde yeni bir serileştirici oluşturmak istemediğiniz için şunu ekleyebilirsiniz:
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);
}
}
Bu sınıf genel DEĞİLSE, sınıfın her örneği aynı kullanırdı _typeSpecificSerializer
.
Ancak genel olduğu için, aynı türden bir örnek kümesi T
tek bir örneğini _typeSpecificSerializer
(belirli bir tür için oluşturulacak) paylaşırken , farklı türdeki T
örnekler farklı örneklerini kullanacaktır _typeSpecificSerializer
.
Bir örnek
Şu iki sınıfı sağladı 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; }
}
... kullanalım:
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();
Bu durumda, başlık altında, firstInst
ve secondInst
aynı sınıf (yani örnekleri olur SerializableEntity<MyFirstEntity>
), ve bu şekilde, bunlar bir örneğini paylaşır _typeSpecificSerializer
.
thirdInst
ve fourthInst
başka bir sınıf (örnekleridir SerializableEntity<OtherEntity>
) ve bu yüzden bir örneğini paylaşacak _typeSpecificSerializer
yani farklı diğer ikisi.
Bu, varlık türlerinizin her biri için farklı serileştirici örnekleri aldığınız anlamına gelir , ancak bunları her gerçek türün bağlamında statik tutar (yani, belirli bir türdeki örnekler arasında paylaşılır).