Geçersiz Kılma ve Yeni Anahtar Sözcüklerle Sürüm Oluşturma (C# Programlama Kılavuzu)
C# dili, farklı kitaplıklardaki temel ve türetilmiş sınıflar arasında sürüm oluşturmanın gelişebilmesi ve geriye dönük uyumluluğu koruyabilmesi için tasarlanmıştır. Bu, örneğin, türetilmiş bir sınıftaki üyeyle aynı ada sahip bir temel sınıfa yeni bir üyenin eklenmesinin C# tarafından tamamen desteklendiği ve beklenmeyen davranışlara yol açmadığı anlamına gelir. Ayrıca bir sınıfın, bir yöntemin devralınan bir yöntemi geçersiz kılmaya yönelik olup olmadığını veya yöntemin benzer adlandırılmış devralınan bir yöntemi gizleyen yeni bir yöntem olup olmadığını açıkça belirtmesi gerektiği anlamına gelir.
C# dilinde türetilmiş sınıflar, temel sınıf yöntemleriyle aynı ada sahip yöntemler içerebilir.
Türetilmiş sınıftaki yöntemden önce yeni veya geçersiz kılma anahtar sözcükleri yoksa, derleyici bir uyarı yayınlar ve yöntem anahtar sözcük mevcut gibi
new
davranır.Türetilmiş sınıftaki yöntemin
new
başında anahtar sözcüğü varsa, yöntemi temel sınıftaki yöntemden bağımsız olarak tanımlanır.Türetilmiş sınıftaki yöntemin
override
önünde anahtar sözcüğü varsa, türetilmiş sınıfın nesneleri temel sınıf yöntemi yerine bu yöntemi çağırır.Anahtar sözcüğünü
override
türetilmiş sınıftaki yöntemine uygulamak için temel sınıf yönteminin sanal olarak tanımlanması gerekir.Temel sınıf yöntemi, anahtar sözcüğü kullanılarak türetilmiş sınıfın
base
içinden çağrılabilir.override
,virtual
venew
anahtar sözcükleri özelliklere, dizin oluşturuculara ve olaylara da uygulanabilir.
Varsayılan olarak, C# yöntemleri sanal değildir. Bir yöntem sanal olarak bildirilirse, yöntemini devralan herhangi bir sınıf kendi sürümünü uygulayabilir. Bir yöntemi sanal yapmak için değiştirici, virtual
temel sınıfın yöntem bildiriminde kullanılır. Türetilmiş sınıf daha sonra anahtar sözcüğünü kullanarak temel sanal yöntemi geçersiz kılabilir veya anahtar sözcüğünü kullanarak override
new
temel sınıftaki sanal yöntemi gizleyebilir. override
Anahtar sözcük veya new
anahtar sözcük belirtilmezse, derleyici bir uyarı yayınlar ve türetilmiş sınıftaki yöntemi temel sınıftaki yöntemi gizler.
Bunu uygulamada göstermek için, bir an için A Şirketinin programınızın kullandığı adlı GraphicsClass
bir sınıf oluşturduğunu varsayalım. Aşağıdakiler şunlardır GraphicsClass
:
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
}
Şirketiniz bu sınıfı kullanır ve yeni bir yöntem ekleyerek kendi sınıfınızı türetmek için bu sınıfı kullanırsınız:
class YourDerivedGraphicsClass : GraphicsClass
{
public void DrawRectangle() { }
}
Şirket A, aşağıdaki koda benzeyen yeni bir sürümünü GraphicsClass
yayınlayana kadar uygulamanız sorunsuz bir şekilde kullanılır:
class GraphicsClass
{
public virtual void DrawLine() { }
public virtual void DrawPoint() { }
public virtual void DrawRectangle() { }
}
öğesinin GraphicsClass
yeni sürümü adlı DrawRectangle
bir yöntem içeriyor. Başlangıçta hiçbir şey gerçekleşmez. Yeni sürüm hala eski sürümle uyumlu ikilidir. Dağıttığınız tüm yazılımlar, yeni sınıf bu bilgisayar sistemlerinde yüklü olsa bile çalışmaya devam eder. yöntemine DrawRectangle
yapılan tüm mevcut çağrılar, türetilmiş sınıfınızdaki sürümünüze başvurmaya devam eder.
Ancak, uygulamasını yeni sürümünü GraphicsClass
kullanarak yeniden derlediğiniz anda, derleyici olan CS0108'den bir uyarı alırsınız. Bu uyarı, yönteminizin uygulamanızda nasıl davranmasını istediğinizi düşünmeniz DrawRectangle
gerektiğini size bildirir.
Yönteminizin yeni temel sınıf yöntemini geçersiz kılmasını istiyorsanız anahtar sözcüğünü override
kullanın:
class YourDerivedGraphicsClass : GraphicsClass
{
public override void DrawRectangle() { }
}
override
anahtar sözcüğü, öğesinden YourDerivedGraphicsClass
türetilen tüm nesnelerin türetilmiş sınıf sürümünü DrawRectangle
kullanmasını sağlar. öğesinden YourDerivedGraphicsClass
türetilen nesneler, temel anahtar sözcüğünü kullanarak temel sınıf sürümüne DrawRectangle
erişmeye devam edebilir:
base.DrawRectangle();
Yönteminizin yeni temel sınıf yöntemini geçersiz kılmasını istemiyorsanız, aşağıdaki önemli noktalar geçerlidir. İki yöntem arasındaki karışıklığı önlemek için yönteminizi yeniden adlandırabilirsiniz. Bu, zaman alıcı ve hataya eğilimli olabilir ve bazı durumlarda pratik değildir. Ancak, projeniz görece küçükse, visual studio'nun Yeniden düzenleme seçeneklerini kullanarak yöntemi yeniden adlandırabilirsiniz. Daha fazla bilgi için bkz. Sınıfları ve Türleri Yeniden Düzenleme (Sınıf Tasarım Aracı).
Alternatif olarak, türetilmiş sınıf tanımınızda anahtar sözcüğünü new
kullanarak uyarıyı engelleyebilirsiniz:
class YourDerivedGraphicsClass : GraphicsClass
{
public new void DrawRectangle() { }
}
anahtar sözcüğünü new
kullanmak derleyiciye tanımınızın temel sınıfta yer alan tanımı gizlediğini bildirir. Bu varsayılan davranıştır.
Geçersiz Kılma ve Yöntem Seçimi
Bir yöntem bir sınıfta adlandırıldığında, C# derleyicisi çağrıyla uyumlu birden fazla yöntem varsa çağrılabilecek en iyi yöntemi seçer; örneğin, aynı ada sahip iki yöntem ve geçirilen parametreyle uyumlu parametreler olduğunda. Aşağıdaki yöntemler uyumlu olabilir:
public class Derived : Base
{
public override void DoWork(int param) { }
public void DoWork(double param) { }
}
bir örneğinde çağrıldığındaDoWork
, C# derleyicisi çağrıyı ilk olarak üzerinde Derived
bildirilen sürümleriyle DoWork
uyumlu hale getirmeye Derived
çalışır. Geçersiz kılma yöntemleri bir sınıfta bildirilir olarak kabul edilmez, temel sınıf üzerinde bildirilen bir yöntemin yeni uygulamalarıdır. Yalnızca C# derleyicisi üzerindeki özgün bir yöntemle Derived
yöntem çağrısıyla eşleşemezse, çağrıyı aynı ad ve uyumlu parametrelerle geçersiz kılınan bir yöntemle eşleştirmeyi dener. Örneğin:
int val = 5;
Derived d = new Derived();
d.DoWork(val); // Calls DoWork(double).
Değişkeni val
örtük olarak çifte dönüştürülebildiğinden C# derleyicisi DoWork(int)
yerine öğesini çağırırDoWork(double)
. Bunu önlemenin iki yolu vardır. İlk olarak, sanal yöntemlerle aynı ada sahip yeni yöntemler bildirmekten kaçının. İkinci olarak, C# derleyicisine örneğini öğesine dönüştürerek temel sınıf yöntemi listesinde arama yapmasını sağlayarak sanal yöntemi çağırmasını Derived
sağlayabilirsiniz Base
. yöntemi sanal olduğundan , uygulaması DoWork(int)
Derived
çağrılır. Örneğin:
((Base)d).DoWork(val); // Calls DoWork(int) on Derived.
ve override
hakkında daha fazla örnek için new
bkz. Geçersiz Kılma ve Yeni Anahtar Sözcüklerin Ne Zaman Kullanılacağını Bilmek.