Mümkün
tl; dr - İsterseniz bir ayarlayıcıyla salt get yöntemini geçersiz kılabilirsiniz. Temel olarak sadece:
Bir oluşturun new
a hem sahiptir özelliğini get
ve set
aynı adı kullanarak.
Başka bir şey yapmazsanız get
, türetilmiş sınıf temel türü üzerinden çağrıldığında eski yöntem çağrılır. Bunu düzeltmek için, yeni yöntemin sonucunu döndürmeye zorlamak üzere eski yöntemde abstract
kullanılan bir ara katman ekleyin .override
get
get
Bu, özellikleri temel tanımlarında eksik olsalar bile get
/ ile özellikleri geçersiz kılmamızı sağlar set
.
Bonus olarak, isterseniz dönüş türünü de değiştirebilirsiniz.
Temel tanım get
-sadece ise, daha türetilmiş bir dönüş türü kullanabilirsiniz.
Temel tanım set
-sadece ise, daha az türetilmiş bir dönüş türü olabilirsiniz.
Temel tanım zaten get
/ set
ise:
Her durumda, isterseniz aynı dönüş türünü koruyabilirsiniz. Aşağıdaki örnekler basitlik için aynı dönüş türünü kullanır.
Durum: Önceden var olan get
-sadece mülk
Değiştiremeyeceğiniz bir sınıf yapınız var. Belki de sadece bir sınıftır ya da önceden var olan bir miras ağacıdır. Durum ne olursa olsun, set
bir mülke yöntem eklemek istersiniz , ancak yapamazsınız.
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
Sorun: Yapamam -sadece ile /override
get
get
set
override
Bir get
/ set
özelliği ile istersiniz , ancak derlenmez.
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
Çözüm: abstract
Ara katman kullanın
Doğrudan override
bir get
/ set
mülkle yapamasanız da şunları yapabilirsiniz :
Aynı ada sahip bir new
get
/ set
özellik oluşturun .
override
eski get
yöntemi get
tutarlılık sağlamak için yeni yöntem bir erişimci ile .
Yani, önce abstract
ara katmanı yazıyorsunuz :
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
Sonra, daha önce derlenmeyecek sınıfı yazarsınız. Bu aslında çünkü bu sefer derlersiniz override
'ing get
-sadece özelliği; bunun yerine, new
anahtar kelimeyi kullanarak değiştirebilirsiniz .
public class D : C
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } }
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
Sonuç: Her şey işe yarıyor!
Açıkçası, bu amaçlandığı gibi çalışıyor D
.
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
test.X = 7;
Print(test.X); // Prints "7", as intended.
D
Temel sınıflarından biri olarak görüntülerken , her şey hala amaçlandığı gibi çalışır , örneğin A
veya B
. Ancak, çalışmasının nedeni biraz daha az belirgin olabilir.
var test = new D() as B;
//test.X = 7; // This won't compile, because test looks like a B,
// and B still doesn't provide a visible setter.
Bununla birlikte, temel sınıf tanımı get
sonuçta türetilmiş sınıfın tanımı ile geçersiz kılınır get
, bu yüzden hala tamamen tutarlıdır.
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
var baseTest = test as A;
Print(test.X); // Prints "7", as intended.
Tartışma
Bu yöntem, -only özelliklerine set
yöntem eklemenizi sağlar get
. Ayrıca, aşağıdakileri yapmak için de kullanabilirsiniz:
Temel sınıfta ne olursa olsun, herhangi bir özelliği get
-sadece, set
-sadece veya get
-ve- set
özellik olarak değiştirin.
Türetilmiş sınıflarda bir yöntemin dönüş türünü değiştirin.
Ana dezavantajları, daha fazla kodlama abstract class
ve miras ağacında ekstra bir şey olmasıdır . Bu, parametre alan yapıcılar için biraz can sıkıcı olabilir, çünkü bunların ara katmana kopyalanması / yapıştırılması gerekir.