18 Arabirim
18.1 Genel
Arabirim bir sözleşme tanımlar. Arabirim uygulayan bir sınıf veya yapı, sözleşmesine uymalıdır. Bir arabirim birden çok temel arabirimden devralabilir ve bir sınıf veya yapı birden çok arabirim uygulayabilir.
Arabirimler yöntemler, özellikler, olaylar ve dizin oluşturucular içerebilir. Arabirimin kendisi, bildirdiği üyeler için uygulama sağlamaz. Arabirim yalnızca arabirimi uygulayan sınıflar veya yapılar tarafından sağlanacak üyeleri belirtir.
18.2 Arabirim bildirimleri
18.2.1 Genel
interface_declaration, yeni bir arabirim türü bildiren bir type_declaration (§14.7) olur.
interface_declaration
: attributes? interface_modifier* 'partial'? 'interface'
identifier variant_type_parameter_list? interface_base?
type_parameter_constraints_clause* interface_body ';'?
;
interface_declaration isteğe bağlı bir öznitelik kümesinden (§22) ve ardından isteğe bağlı bir interface_modifierkümesinden (§18.2.2) ve ardından isteğe bağlı kısmi değiştiriciden (§15.2.7) ve ardından anahtar sözcük interface
ve arabirimi adlandıran bir tanımlayıcıdan ve ardından isteğe bağlı variant_type_parameter_list belirtimlerinden (§18.2.3) ve ardından isteğe bağlı bir interface_base oluşur specification (§18.2.4), ardından isteğe bağlı bir type_parameter_constraints_clausebelirtimi (§15.2.5) ve ardından interface_body (§18.3) ve isteğe bağlı olarak noktalı virgül.
Arabirim bildirimi, variant_type_parameter_list sağlamadığı sürece bir type_parameter_constraints_clause sağlamaz.
variant_type_parameter_list sağlayan arabirim bildirimi genel arabirim bildirimidir. Ayrıca, genel bir sınıf bildiriminin veya genel yapı bildiriminin içinde iç içe yerleştirilmiş tüm arabirimler kendisi genel bir arabirim bildirimidir, çünkü içeren türün tür bağımsız değişkenleri, oluşturulmuş bir tür (§8.4) oluşturmak için sağlanmalıdır.
18.2.2 Arabirim değiştiricileri
bir interface_declaration isteğe bağlı olarak bir dizi arabirim değiştirici içerebilir:
interface_modifier
: 'new'
| 'public'
| 'protected'
| 'internal'
| 'private'
| unsafe_modifier // unsafe code support
;
unsafe_modifier (§23.2) yalnızca güvenli olmayan kodda (§23) kullanılabilir.
Aynı değiştiricinin bir arabirim bildiriminde birden çok kez görünmesi bir derleme zamanı hatasıdır.
new
Değiştiriciye yalnızca bir sınıf içinde tanımlanan arabirimlerde izin verilir. Arabirimin devralınan bir üyeyi §15.3.5'te açıklandığı gibi aynı ada göre gizlediğini belirtir.
public
, protected
, internal
ve private
değiştiricileri arabirimin erişilebilirliğini denetler. Arabirim bildiriminin gerçekleştiği bağlama bağlı olarak, bu değiştiricilerin yalnızca bazılarına izin verilebileceği (§7.5.2). Kısmi tür bildirimi (§15.2.7) bir erişilebilirlik belirtimi içerdiğinde (, public
, protected
ve internal
değiştiricileri aracılığıylaprivate
), §15.2.2'deki kurallar geçerlidir.
18.2.3 Değişken türü parametre listeleri
18.2.3.1 Genel
Değişken türü parametre listeleri yalnızca arabirim ve temsilci türlerinde oluşabilir. Sıradan type_parameter_list'lerdenfarkı, her tür parametresindeki isteğe bağlı variance_annotation .
variant_type_parameter_list
: '<' variant_type_parameters '>'
;
variant_type_parameters
: attributes? variance_annotation? type_parameter
| variant_type_parameters ',' attributes? variance_annotation?
type_parameter
;
variance_annotation
: 'in'
| 'out'
;
Varyans ek açıklaması ise out
tür parametresinin birlikte değişken olduğu söylenir. Varyans ek açıklaması ise in
tür parametresinin değişkensiz olduğu söylenir. Varyans ek açıklaması yoksa tür parametresinin sabit olduğu söylenir.
Örnek: Aşağıdakilerde:
interface C<out X, in Y, Z> { X M(Y y); Z P { get; set; } }
X
kovaryant,Y
kontravariant veZ
sabittir.son örnek
Genel bir arabirim birden çok bölümde (§15.2.3) bildirilirse, her kısmi bildirim her tür parametresi için aynı varyansı belirtecektir.
18.2.3.2 Varyans güvenliği
Türün tür parametre listesinde varyans ek açıklamalarının oluşumu, tür bildiriminde türlerin oluşabileceği yerleri kısıtlar.
Aşağıdakilerden biri barındırılıyorsa, T türü çıkış güvensizdir:
-
T
değişken karşıtı bir tür parametresidir -
T
çıkış-güvensiz öğe türüne sahip bir dizi türüdür -
T
, aşağıdakilerden en az birininSᵢ,... Aₑ
tutulduğu genel bir türden oluşturulan bir arabirim veya temsilci türüdür:S<Xᵢ, ... Xₑ>
Aᵢ
-
Xᵢ
kovaryant veya sabittir veAᵢ
çıkış güvenli değildir. -
Xᵢ
değişken veya sabittir veAᵢ
girişe güvenli değildir.
-
Aşağıdakilerden biri barındırılıyorsa , T türü girişi güvenli değildir:
-
T
ortak değişken türünde bir parametredir -
T
giriş-güvensiz öğe türüne sahip bir dizi türüdür -
T
, aşağıdakilerden en az birininS<Aᵢ,... Aₑ>
tutulduğu genel bir türden oluşturulan bir arabirim veya temsilci türüdür:S<Xᵢ, ... Xₑ>
Aᵢ
-
Xᵢ
kovaryant veya sabittir veAᵢ
giriş güvenli değildir. -
Xᵢ
değişken veya sabittir veAᵢ
çıkış-güvensizdir.
-
Sezgisel olarak, çıkış konumunda güvenli olmayan bir çıkış türü yasaktır ve giriş konumunda güvenli olmayan giriş türü yasaktır.
Bir tür çıkış-güvenli değilse çıkış-güvenli ve giriş-güvensiz değilse giriş-güvenlidir.
18.2.3.3 Varyans dönüştürme
Varyans ek açıklamalarının amacı, arabirim ve temsilci türlerine daha yumuşak (ancak yine de güvenli tür) dönüştürmeler sağlamaktır. Bu amaçla örtük (§10.2) ve açık dönüştürme (§10.3) tanımları, aşağıdaki gibi tanımlanan varyans-dönüştürülebilirlik kavramını kullanır:
T<Aᵢ, ..., Aᵥ>
Tür, değişken türü T<Bᵢ, ..., Bᵥ>
parametreleriyle bildirilen bir arabirim veya temsilci türüyse T
ve her değişken türü parametresi T<Xᵢ, ..., Xᵥ>
Xᵢ
için aşağıdakilerden biri tutulur:
-
Xᵢ
birlikte değişkendir ve ile arasında örtük bir başvuru veya kimlik dönüştürmesi vardırAᵢ
Bᵢ
-
Xᵢ
değişkenden bağımsızdır ve ile arasında örtük bir başvuru veya kimlik dönüştürmesi vardırBᵢ
Aᵢ
-
Xᵢ
sabittir ve bir kimlik dönüştürmesiAᵢ
Bᵢ
18.2.4 Temel arabirimler
Bir arabirim, arabirimin açık temel arabirimleri olarak adlandırılan sıfır veya daha fazla arabirim türünden devralabilir. Bir arabirimde bir veya daha fazla açık temel arabirim olduğunda, bu arabirimin bildiriminde arabirim tanımlayıcısını iki nokta üst üste ve virgülle ayrılmış temel arabirim türlerinin listesi izler.
interface_base
: ':' interface_type_list
;
Açık temel arabirimler arabirim türleri (§8.4, §18.2) oluşturulabilir. Temel arabirim kendi başına bir tür parametresi olamaz, ancak kapsamdaki tür parametrelerini içerebilir.
Oluşturulan arabirim türü için, açık temel arabirimler genel tür bildiriminde açık temel arabirim bildirimleri alınarak ve temel arabirim bildirimindeki her type_parameter için oluşturulan türün ilgili type_argument değiştirilerek oluşturulur.
Bir arabirimin açık taban arabirimleri en az arabirimin kendisi kadar erişilebilir olmalıdır (§7.5.5).
Not: Örneğin, bir arabirimin interface_base veya
private
internal
arabirimini belirtmek birpublic
derleme zamanı hatasıdır. son not
Bir arabirimin doğrudan veya dolaylı olarak kendisinden devraldığı derleme zamanı hatasıdır.
Bir arabirimin temel arabirimleri açık temel arabirimler ve bunların temel arabirimleridir. Başka bir deyişle, temel arabirim kümesi, açık temel arabirimlerin, bunların açık temel arabirimlerinin vb. tam geçişli kapanışıdır. Arabirim, temel arabirimlerinin tüm üyelerini devralır.
Örnek: Aşağıdaki kodda
interface IControl { void Paint(); } interface ITextBox : IControl { void SetText(string text); } interface IListBox : IControl { void SetItems(string[] items); } interface IComboBox: ITextBox, IListBox {}
temel arabirimleri
IComboBox
,IControl
veITextBox
şeklindedirIListBox
. Başka bir deyişle,IComboBox
yukarıdaki arabirim ve üyeleriniSetText
SetItems
Paint
devralır.son örnek
Yapılı bir genel türden devralınan üyeler, tür değişiminden sonra devralınır. Diğer bir ifadeyle, üyedeki tüm bileşenler temel sınıf bildiriminin tür parametrelerinin yerine class_base belirtiminde kullanılan ilgili tür bağımsız değişkenleri kullanılır.
Örnek: Aşağıdaki kodda
interface IBase<T> { T[] Combine(T a, T b); } interface IDerived : IBase<string[,]> { // Inherited: string[][,] Combine(string[,] a, string[,] b); }
tür parametresi
IDerived
ile değiştirildikten sonra arabirimiCombine
yöntemini devralırT
string[,]
.son örnek
Arabirim uygulayan bir sınıf veya yapı, arabirimin tüm temel arabirimlerini de örtük olarak uygular.
Kısmi arabirim bildiriminin (§15.2.7) birden çok parçasındaki arabirimlerin işlenmesi ,15.2.4.3'te daha ayrıntılı olarak ele alınıyor.
Bir arabirimin her temel arabirimi çıkış açısından güvenli olmalıdır (§18.2.3.2).
18.3 Arabirim gövdesi
Arabirimin interface_body , arabirimin üyelerini tanımlar.
interface_body
: '{' interface_member_declaration* '}'
;
18.4 Arabirim üyeleri
18.4.1 Genel
Bir arabirimin üyeleri, temel arabirimlerden devralınan üyeler ve arabirimin kendisi tarafından bildirilen üyelerdir.
interface_member_declaration
: interface_method_declaration
| interface_property_declaration
| interface_event_declaration
| interface_indexer_declaration
;
Arabirim bildirimi sıfır veya daha fazla üye bildirir. Bir arabirimin üyeleri yöntemler, özellikler, olaylar veya dizin oluşturucular olmalıdır. Arabirim sabitler, alanlar, işleçler, örnek oluşturucuları, sonlandırıcılar veya türler içeremez veya herhangi bir türdeki statik üyeleri içeremez.
Tüm arabirim üyeleri örtük olarak genel erişime sahiptir. Arabirim üyesi bildirimlerinin değiştiricileri içermesi bir derleme zamanı hatasıdır.
interface_declaration yeni bir bildirim alanı (§7.3) oluşturur ve interface_declaration hemen içerdiği tür parametreleri ve interface_member_declaration bu bildirim alanına yeni üyeler ekler. Aşağıdaki kurallar interface_member_declarationiçin geçerlidir:
- Bir arabirim bildiriminin variant_type_parameter_list bir tür parametresinin adı, aynı variant_type_parameter_list diğer tüm tür parametrelerinin adlarından farklı olmalıdır ve arabirimin tüm üyelerinin adlarından farklıdır.
- Bir yöntemin adı, aynı arabirimde bildirilen tüm özelliklerin ve olayların adlarından farklı olmalıdır. Ayrıca, bir yöntemin imzası (§7.6) aynı arabirimde bildirilen diğer tüm yöntemlerin imzalarından farklı olacaktır ve aynı arabirimde bildirilen iki yöntem yalnızca ,
in
veout
ileref
farklı imzalara sahip olmayacaktır. - Bir özelliğin veya olayın adı, aynı arabirimde bildirilen diğer tüm üyelerin adlarından farklı olacaktır.
- Bir dizin oluşturucunun imzası, aynı arabirimde bildirilen diğer tüm dizin oluşturucuların imzalarından farklı olmalıdır.
Bir arabirimin devralınan üyeleri, özellikle arabirimin bildirim alanının bir parçası değildir. Bu nedenle, bir arabirimin devralınan üyeyle aynı ada veya imzaya sahip bir üyeyi bildirmesine izin verilir. Bu durum oluştuğunda, türetilmiş arabirim üyesinin temel arabirim üyesini gizley dediği söylenir. Devralınan bir üyenin gizlenmesi hata olarak kabul edilmez, ancak derleyicinin uyarı vermesine neden olur. Uyarıyı bastırmak için, türetilmiş arabirim üyesinin bildiriminde, türetilen üyenin temel üyeyi gizlemeye yönelik olduğunu belirten bir new
değiştirici bulunacaktır. Bu konu §7.7.2.3'te daha ayrıntılı olarak ele alınmıştır.
Devralınan bir new
üyeyi gizlemeyen bir bildirime değiştirici eklenirse, bu etkiye bir uyarı verilir. Değiştirici kaldırılarak bu uyarı gizleniyor new
.
Not: Sınıftaki
object
üyeler hiçbir arabirimin (§18.4) üyesi değildir. Ancak, sınıftakiobject
üyeler herhangi bir arabirim türünde (§12.5) üye arama yoluyla kullanılabilir. son not
Birden çok bölümde bildirilen bir arabirimin üyeleri kümesi (§15.2.7), her bölümde bildirilen üyelerin birleşimidir. Arabirim bildiriminin tüm bölümlerinin gövdeleri aynı bildirim alanını (§7.3) paylaşır ve her üyenin (§7.7) kapsamı tüm parçaların gövdelerine kadar uzanır.
18.4.2 Arabirim yöntemleri
Arabirim yöntemleri interface_method_declarationkullanılarak bildirilir:
interface_method_declaration
: attributes? 'new'? return_type interface_method_header
| attributes? 'new'? ref_kind ref_return_type interface_method_header
;
interface_method_header
: identifier '(' parameter_list? ')' ';'
| identifier type_parameter_list '(' parameter_list? ')'
type_parameter_constraints_clause* ';'
;
Arabirim yöntemi bildiriminin öznitelikleri, return_type, ref_return_type, tanımlayıcısı ve parameter_list , bir sınıftaki yöntem bildiriminin (§15.6) anlamlarıyla aynı anlama sahiptir. Arabirim yöntemi bildiriminin bir yöntem gövdesi belirtmesine izin verilmez ve bu nedenle bildirim her zaman noktalı virgülle biter.
Bir arabirim yönteminin tüm parametre türleri giriş-güvenli (§18.2.3.2) ve dönüş türü ya da void
çıkış-güvenli olmalıdır. Ayrıca, tüm çıkış veya başvuru parametre türleri de çıkış açısından güvenli olmalıdır.
Not: Yaygın uygulama kısıtlamaları nedeniyle çıkış parametrelerinin giriş açısından güvenli olması gerekir. son not
Ayrıca, yöntemin herhangi bir tür parametresinde her sınıf türü kısıtlaması, arabirim türü kısıtlaması ve tür parametresi kısıtlaması giriş açısından güvenli olacaktır.
Ayrıca, yöntemin herhangi bir tür parametresindeki her sınıf türü kısıtlaması, arabirim türü kısıtlaması ve tür parametresi kısıtlaması giriş açısından güvenli olacaktır.
Bu kurallar, arabirimin herhangi bir kovarant veya değişken karşıtı kullanımının tür güvenli kalmasını sağlar.
Örnek:
interface I<out T> { void M<U>() where U : T; // Error }
türü parametre kısıtlaması
T
U
olarak kullanımı giriş açısından güvenli olmadığından kötü biçimlendirilmiş.Bu kısıtlamanın yapılmaması durumunda tür güvenliğini aşağıdaki şekilde ihlal etmek mümkün olacaktır:
class B {} class D : B {} class E : B {} class C : I<D> { public void M<U>() {...} } ... I<B> b = new C(); b.M<E>();
Bu aslında için bir çağrıdır
C.M<E>
. Ancak bu çağrı için türündenE
D
türetilmesi gerekir, bu nedenle tür güvenliği burada ihlal edilir.son örnek
18.4.3 Arabirim özellikleri
Arabirim özellikleri interface_property_declarationkullanılarak bildirilir:
interface_property_declaration
: attributes? 'new'? type identifier '{' interface_accessors '}'
| attributes? 'new'? ref_kind type identifier '{' ref_interface_accessor '}'
;
interface_accessors
: attributes? 'get' ';'
| attributes? 'set' ';'
| attributes? 'get' ';' attributes? 'set' ';'
| attributes? 'set' ';' attributes? 'get' ';'
;
ref_interface_accessor
: attributes? 'get' ';'
;
Arabirim özellik bildiriminin öznitelikleri, türü ve tanımlayıcısı , bir sınıftaki (§15.7) özellik bildiriminin anlamlarıyla aynı anlama sahiptir.
Arabirim özellik bildiriminin erişimcileri, accessor_body her zaman noktalı virgül olması dışında, sınıf özellik bildiriminin(§15.7.3) erişimcilerine karşılık gelir. Bu nedenle, erişimciler özelliğin salt okunur mu yoksa salt okunur mu olduğunu gösterir.
Bir arabirim özelliğinin türü, bir alma aksesuarı varsa çıkış açısından güvenli olmalı ve set erişimcisi varsa giriş-güvenli olacaktır.
18.4.4 Arabirim olayları
Arabirim olayları interface_event_declarationkullanılarak bildirilir:
interface_event_declaration
: attributes? 'new'? 'event' type identifier ';'
;
Arabirim olay bildiriminin öznitelikleri, türü ve tanımlayıcısı , bir sınıftaki olay bildiriminin (§15.8) anlamlarıyla aynı anlama sahiptir.
Bir arabirim olayının türü giriş açısından güvenli olmalıdır.
18.4.5 Arabirim dizin oluşturucuları
Arabirim dizin oluşturucuları interface_indexer_declarationkullanılarak bildirilir:
interface_indexer_declaration
: attributes? 'new'? type 'this' '[' parameter_list ']'
'{' interface_accessors '}'
| attributes? 'new'? ref_kind type 'this' '[' parameter_list ']'
'{' ref_interface_accessor '}'
;
Arabirim dizin oluşturucu bildiriminin öznitelikleri, türü ve parameter_list , bir sınıftaki dizin oluşturucu bildirimiyle (§15.9) aynı anlama sahiptir.
Arabirim dizin oluşturucu bildiriminin erişimcileri, accessor_body her zaman noktalı virgül olması dışında, sınıf dizin oluşturucu bildiriminin(§15.9) erişimcilerine karşılık gelir. Bu nedenle, erişimciler yalnızca dizin oluşturucunun salt okunur mu yoksa salt okunur mu olduğunu belirtir.
Arabirim dizin oluşturucusunun tüm parametre türleri giriş açısından güvenli olmalıdır (§18.2.3.2). Ayrıca, tüm çıkış veya başvuru parametre türleri de çıkış açısından güvenli olmalıdır.
Not: Yaygın uygulama kısıtlamaları nedeniyle çıkış parametrelerinin giriş açısından güvenli olması gerekir. son not
Bir arabirim dizin oluşturucunun türü, bir alma aksesuarı varsa çıkış açısından güvenli olmalı ve set erişimcisi varsa girişe güvenli olacaktır.
18.4.6 Arabirim üyesi erişimi
Arabirim üyelerine üye erişimi (§12.8.7) ve dizin oluşturucu erişimi (§12.8.12.3) form I.M
ve I[A]
ifadeleri aracılığıyla erişilir; burada I
bir arabirim türüdür, M
, bu arabirim türünün bir yöntemi, özelliği veya olayıdır ve A
bir dizin oluşturucu bağımsız değişken listesidir.
Kesin olarak tek devralma olan arabirimler için (devralma zincirindeki her arabirim tam olarak sıfır veya bir doğrudan temel arabirime sahiptir), üye aramasının etkileri (§12.5), yöntem çağırma (§12.8.1 0.2) ve dizin oluşturucu erişimi (§12.8.12.3) kuralları, sınıflar ve yapılar ile tamamen aynıdır: Daha fazla türetilmiş üye, aynı ada veya imzaya sahip daha az türetilmiş üyeleri gizler. Ancak, birden çok devralma arabirimleri için, iki veya daha fazla ilişkisiz temel arabirim aynı ada veya imzaya sahip üyeleri bildirdiğinde belirsizlikler oluşabilir. Bu alt bölümde, bazıları belirsizliklere, bazıları ise belirsizliğe yol açan ve olmayan bazı örnekler gösterilir. Her durumda, açık atamalar belirsizlikleri çözmek için kullanılabilir.
Örnek: Aşağıdaki kodda
interface IList { int Count { get; set; } } interface ICounter { void Count(int i); } interface IListCounter : IList, ICounter {} class C { void Test(IListCounter x) { x.Count(1); // Error x.Count = 1; // Error ((IList)x).Count = 1; // Ok, invokes IList.Count.set ((ICounter)x).Count(1); // Ok, invokes ICounter.Count } }
içindeki üye araması (§12.5) belirsiz olduğundan ilk iki deyim derleme zamanı hatalarına
Count
IListCounter
neden olur. Örnekte gösterildiği gibi belirsizlik, uygun temel arabirim türüne geçirilerekx
çözümlenir. Bu tür atamaların çalışma zamanı maliyeti yoktur; yalnızca örneği derleme zamanında daha az türetilmiş bir tür olarak görüntülemektir.son örnek
Örnek: Aşağıdaki kodda
interface IInteger { void Add(int i); } interface IDouble { void Add(double d); } interface INumber : IInteger, IDouble {} class C { void Test(INumber n) { n.Add(1); // Invokes IInteger.Add n.Add(1.0); // Only IDouble.Add is applicable ((IInteger)n).Add(1); // Only IInteger.Add is a candidate ((IDouble)n).Add(1); // Only IDouble.Add is a candidate } }
çağrısı
n.Add(1)
, §12.6.4IInteger.Add
uygulayarak seçer. Benzer şekilde, çağrın.Add(1.0)
öğesini seçerIDouble.Add
. Açık atamalar eklendiğinde yalnızca bir aday yöntemi vardır ve bu nedenle belirsizlik yoktur.son örnek
Örnek: Aşağıdaki kodda
interface IBase { void F(int i); } interface ILeft : IBase { new void F(int i); } interface IRight : IBase { void G(); } interface IDerived : ILeft, IRight {} class A { void Test(IDerived d) { d.F(1); // Invokes ILeft.F ((IBase)d).F(1); // Invokes IBase.F ((ILeft)d).F(1); // Invokes ILeft.F ((IRight)d).F(1); // Invokes IBase.F } }
IBase.F
üye tarafından gizlenirILeft.F
. Bu nedenle çağrıd.F(1)
, üzerinden geçenILeft.F
erişim yolunda gizli görünmeseIBase.F
de öğesini seçerIRight
.Birden çok devralma arabirimlerinde gizlemeye yönelik sezgisel kural şudur: Bir üye herhangi bir erişim yolunda gizlenirse, tüm erişim yollarında gizlenir. öğesinden öğesine erişim yolu gizlendiğinden
IDerived
, üye ile arasındaki erişim yolunda da gizlenirILeft
IBase
IBase.F
.IDerived
IRight
IBase
son örnek
18.5 Nitelenmiş arabirim üye adları
Arabirim üyesine bazen uygun arabirim üyesi adıyla başvurulur. Arabirim üyesinin tam adı, üyenin bildirildiği arabirimin adından, ardından bir nokta ve ardından üyenin adından oluşur. Üyenin tam adı, üyenin bildirildiği arabirime başvurur.
Örnek: Bildirimlere göre
interface IControl { void Paint(); } interface ITextBox : IControl { void SetText(string text); }
öğesinin tam adı
Paint
,IControl.Paint
SetText'in tam adı ise şeklindedirITextBox.SetText
. Yukarıdaki örnekte olarakPaint
başvurmakITextBox.Paint
mümkün değildir.son örnek
Arabirim bir ad alanının parçası olduğunda, nitelikli arabirim üyesi adı ad alanı adını içerebilir.
Örnek:
namespace System { public interface ICloneable { object Clone(); } }
Ad alanı içinde
System
, hem hemICloneable.Clone
deSystem.ICloneable.Clone
yöntemi içinClone
uygun arabirim üye adlarıdır.son örnek
18.6 Arabirim uygulamaları
18.6.1 Genel
Arabirimler sınıflar ve yapılar tarafından uygulanabilir. Bir sınıfın veya yapının doğrudan bir arabirim uyguladığını belirtmek için, arabirim sınıfın veya yapının temel sınıf listesine eklenir.
Örnek:
interface ICloneable { object Clone(); } interface IComparable { int CompareTo(object other); } class ListEntry : ICloneable, IComparable { public object Clone() {...} public int CompareTo(object other) {...} }
son örnek
Doğrudan bir arabirim uygulayan bir sınıf veya yapı, arabirimin tüm temel arabirimlerini de örtük olarak uygular. Sınıf veya yapı, temel sınıf listesindeki tüm temel arabirimleri açıkça listelemese bile bu durum geçerlidir.
Örnek:
interface IControl { void Paint(); } interface ITextBox : IControl { void SetText(string text); } class TextBox : ITextBox { public void Paint() {...} public void SetText(string text) {...} }
Burada, sınıfı
TextBox
hem hemIControl
deITextBox
uygular.son örnek
Bir sınıf C
doğrudan bir arabirim uyguladığında, öğesinden C
türetilen tüm sınıflar da örtük olarak arabirimi uygular.
Sınıf bildiriminde belirtilen temel arabirimler arabirim türleri (§8.4, §18.2) oluşturulabilir.
Örnek: Aşağıdaki kod, bir sınıfın oluşturulmuş arabirim türlerini nasıl uygulayabileceğini gösterir:
class C<U, V> {} interface I1<V> {} class D : C<string, int>, I1<string> {} class E<T> : C<int, T>, I1<T> {}
son örnek
Genel sınıf bildiriminin temel arabirimleri , §18.6.3'te açıklanan benzersizlik kuralını karşılayacaktır.
18.6.2 Açık arabirim üyesi uygulamaları
Bir sınıf veya yapı, arabirimleri uygulama amacıyla açık arabirim üyesi uygulamaları bildirebilir. Açık arabirim üyesi uygulaması, uygun arabirim üye adına başvuran bir yöntem, özellik, olay veya dizin oluşturucu bildirimidir.
Örnek:
interface IList<T> { T[] GetElements(); } interface IDictionary<K, V> { V this[K key] { get; } void Add(K key, V value); } class List<T> : IList<T>, IDictionary<int, T> { public T[] GetElements() {...} T IDictionary<int, T>.this[int index] {...} void IDictionary<int, T>.Add(int index, T value) {...} }
Burada
IDictionary<int,T>.this
veIDictionary<int,T>.Add
açık arabirim üyesi uygulamalarıdır.son örnek
Örnek: Bazı durumlarda, bir arabirim üyesinin adı uygulayan sınıf için uygun olmayabilir, bu durumda arabirim üyesi açık arabirim üyesi uygulaması kullanılarak uygulanabilir. Örneğin, dosya soyutlaması uygulayan bir sınıf, büyük olasılıkla dosya kaynağını serbest bırakma etkisine sahip bir
Close
üye işlevi uygular ve açık arabirim üyesi uygulamasını kullanarak arabiriminDispose
yöntemini uygularIDisposable
:interface IDisposable { void Dispose(); } class MyFile : IDisposable { void IDisposable.Dispose() => Close(); public void Close() { // Do what's necessary to close the file System.GC.SuppressFinalize(this); } }
son örnek
Bir yöntem çağırma, özellik erişimi, olay erişimi veya dizin oluşturucu erişiminde uygun arabirim üye adı aracılığıyla açık arabirim üyesi uygulamasına erişmek mümkün değildir. Açık arabirim üyesi uygulamasına yalnızca bir arabirim örneği üzerinden erişilebilir ve bu durumda yalnızca üye adıyla başvurulur.
Açık arabirim üyesi uygulamasının veya dışındaki extern
değiştiricileri (async
) içermesi derleme zamanı hatasıdır.
Açık arabirim yöntemi uygulamasının type_parameter_constraints_clause'leriiçermesi derleme zamanı hatasıdır. Genel bir açık arabirim yöntemi uygulamasına yönelik kısıtlamalar arabirim yönteminden devralınır.
Not: Açık arabirim üyesi uygulamaları diğer üyelerden farklı erişilebilirlik özelliklerine sahiptir. Açık arabirim üyesi uygulamalarına hiçbir zaman bir yöntem çağrısında veya özellik erişiminde uygun arabirim üyesi adı üzerinden erişilemediğinden, bunlar bir anlamda özeldir. Ancak, arabirim üzerinden erişilebildiği için, bir anlamda bildirildikleri arabirim kadar geneldirler. Açık arabirim üyesi uygulamaları iki birincil amaca hizmet eder:
- Açık arabirim üyesi uygulamalarına sınıf veya yapı örnekleri aracılığıyla erişilemediğinden, arabirim uygulamalarının bir sınıfın veya yapının ortak arabiriminden dışlanmasına izin verir. Bu, özellikle bir sınıf veya yapı, bu sınıfın veya yapının tüketicisini ilgilendirmeyen bir iç arabirim uyguladığında kullanışlıdır.
- Açık arabirim üyesi uygulamaları, aynı imzaya sahip arabirim üyelerinin kesinleştirilmesine olanak sağlar. Açık arabirim üyesi uygulamaları olmadan, bir sınıfın veya yapının aynı imzaya ve dönüş türüne sahip arabirim üyelerinin farklı uygulamalarına sahip olması mümkün değildir; aynı imzaya sahip ancak farklı dönüş türlerine sahip tüm arabirim üyelerinde herhangi bir uygulama olması mümkün değildir.
son not
Açık arabirim üyesi uygulamasının geçerli olması için, sınıf veya yapı, temel sınıf listesinde, tam arabirim üyesi adı, türü, tür parametresi sayısı ve parametre türleri açık arabirim üyesi uygulamasınınkilerle tam olarak eşleşen bir üye içeren bir arabirimi adlandırmalıdır. Arabirim işlevi üyesinin parametre dizisi varsa, değiştiriciye sahip olmak params
için ilişkili açık arabirim üyesi uygulamasının karşılık gelen parametresine izin verilir, ancak gerekli değildir. Arabirim işlevi üyesinin parametre dizisi yoksa, ilişkili açık arabirim üyesi uygulaması parametre dizisine sahip olmaz.
Örnek: Bu nedenle, aşağıdaki sınıfta
class Shape : ICloneable { object ICloneable.Clone() {...} int IComparable.CompareTo(object other) {...} // invalid }
temel sınıf listesinde
IComparable.CompareTo
listelenmediğinden ve temel arabirimi olmadığından derleme zamanı hatasıylaIComparable
Shape
sonuç bildirimiICloneable
. Benzer şekilde, bildirimlerdeclass Shape : ICloneable { object ICloneable.Clone() {...} } class Ellipse : Shape { object ICloneable.Clone() {...} // invalid }
içinde bildirimi
ICloneable.Clone
Ellipse
, temel sınıf listesinde açıkça listelenmediğindenICloneable
derleme zamanı hatasıyla sonuçlanırEllipse
.son örnek
Açık arabirim üyesi uygulamasının nitelikli arabirim üyesi adı, üyenin bildirildiği arabirime başvuracaktır.
Örnek: Bu nedenle, bildirimlerde
interface IControl { void Paint(); } interface ITextBox : IControl { void SetText(string text); } class TextBox : ITextBox { void IControl.Paint() {...} void ITextBox.SetText(string text) {...} }
Paint'in açık arabirim üyesi uygulaması olarak
IControl.Paint
yazılmalıdır, olarak yazılmalıdır.ITextBox.Paint
son örnek
18.6.3 Uygulanan arabirimlerin benzersizliği
Genel tür bildirimi tarafından uygulanan arabirimler, olası tüm yapı türleri için benzersiz kalacaktır. Bu kural olmadan, belirli yapılı türler için çağrılacak doğru yöntemi belirlemek mümkün olmazdı.
Örnek: Genel bir sınıf bildiriminin aşağıdaki gibi yazılması için izin verilmiş olduğunu varsayalım:
interface I<T> { void F(); } class X<U ,V> : I<U>, I<V> // Error: I<U> and I<V> conflict { void I<U>.F() {...} void I<V>.F() {...} }
Buna izin verilseydi, aşağıdaki durumda hangi kodun yürütüleceğini belirlemek mümkün olmazdı:
I<int> x = new X<int, int>(); x.F();
son örnek
Genel tür bildiriminin arabirim listesinin geçerli olup olmadığını belirlemek için aşağıdaki adımlar gerçekleştirilir:
- Genel bir sınıf, yapı veya arabirim bildiriminde
L
doğrudan belirtilen arabirimlerin listesi olsunC
. -
L
zaten içindeL
olan arabirimlerin temel arabirimlerine ekleyin. - 'den
L
yinelenenleri kaldırın. - 'den
C
oluşturulan olası bir tür ise, tür bağımsız değişkenleri ileL
değiştirildikten sonra içindeki iki arabiriminL
aynı olmasını sağlar ve bildirimiC
geçersiz olur. Tüm olası yapı türleri belirlenirken kısıtlama bildirimleri dikkate alınmaz.
Not: Yukarıdaki sınıf bildiriminde
X
, arabirim listesiL
vel<U>
'yiI<V>
içerir. ile oluşturulmuş veU
aynı türde olan herhangi bir türV
bu iki arabirimin aynı türlere neden olabileceğinden bildirim geçersizdir. son not
Farklı devralma düzeylerinde belirtilen arabirimlerin birleştirilmesi mümkündür:
interface I<T>
{
void F();
}
class Base<U> : I<U>
{
void I<U>.F() {...}
}
class Derived<U, V> : Base<U>, I<V> // Ok
{
void I<V>.F() {...}
}
Bu kod hem hem de Derived<U,V>
I<U>
uygulasa I<V>
da geçerlidir. Kod
I<int> x = new Derived<int, int>();
x.F();
yöntemini Derived
içinde çağırır çünkü Derived<int,int>'
etkin bir şekilde yeniden uygular I<int>
(§18.6.7).
18.6.4 Genel yöntemlerin uygulanması
Genel bir yöntem örtük olarak bir arabirim yöntemi uyguladığında, her yöntem türü parametresi için verilen kısıtlamalar her iki bildirimde de eşdeğer olacaktır (herhangi bir arabirim türü parametresi uygun tür bağımsız değişkenleriyle değiştirildikten sonra), burada yöntem türü parametreleri soldan sağa sıralı konumlarla tanımlanır.
Örnek: Aşağıdaki kodda:
interface I<X, Y, Z> { void F<T>(T t) where T : X; void G<T>(T t) where T : Y; void H<T>(T t) where T : Z; } class C : I<object, C, string> { public void F<T>(T t) {...} // Ok public void G<T>(T t) where T : C {...} // Ok public void H<T>(T t) where T : string {...} // Error }
yöntemi
C.F<T>
örtük olarak uygularI<object,C,string>.F<T>
. Bu durumda,C.F<T>
tüm tür parametrelerinde örtük bir kısıtlama olduğundanT: object
kısıtlamayıobject
belirtmek için gerekli değildir (veya izin verilmez). Arabirim türü parametreleri karşılık gelen tür bağımsız değişkenleriyle değiştirildikten sonra, kısıtlamalar arabirimdekilerle eşleştiği için yöntemiC.G<T>
örtük olarak uygularI<object,C,string>.G<T>
. Korumalı türler (C.H<T>
bu örnekte) kısıtlama olarak kullanılamadığından yöntemstring
kısıtlaması bir hatadır. Örtük arabirim yöntemi uygulamalarının kısıtlamalarının eşleşmesi gerektiğinden kısıtlamanın atlanması da hata olabilir. Bu nedenle, örtük olarak uygulamakI<object,C,string>.H<T>
mümkün değildir. Bu arabirim yöntemi yalnızca açık bir arabirim üyesi uygulaması kullanılarak uygulanabilir:class C : I<object, C, string> { ... public void H<U>(U u) where U : class {...} void I<object, C, string>.H<T>(T t) { string s = t; // Ok H<T>(t); } }
Bu durumda, açık arabirim üyesi uygulaması kesinlikle daha zayıf kısıtlamalara sahip bir ortak yöntemi çağırır. T'den s'ye atama geçerli çünkü
T
bu kısıtlamaT: string
kaynak kodda ifade edilemez olsa bile kısıtlamasını devralır. son örnek
Not: Genel bir yöntem açıkça bir arabirim yöntemi uyguladığında, uygulayan yöntemde hiçbir kısıtlamaya izin verilmez (§15.7.1, §18.6.2). son not
18.6.5 Arabirim eşlemesi
Sınıf veya yapı, sınıfın veya yapının temel sınıf listesinde listelenen arabirimlerin tüm üyelerinin uygulamalarını sağlayacaktır. Bir uygulama sınıfı veya yapısında arabirim üyelerinin uygulamalarını bulma işlemi, arabirim eşlemesi olarak bilinir.
Bir sınıf veya yapı C
için arabirim eşlemesi, temel sınıf listesinde C
belirtilen her arabirimin her üyesi için bir uygulama bulur. Üyenin bildirildiği arabirim olan belirli bir arabirim üyesinin I.M
uygulaması, ile başlayıp I
bir eşleşme bulunana kadar her bir temel sınıfı M
için yinelenerek her sınıfı veya yapıyı S
inceleyerek belirlenir:C
C
- ve ile eşleşen
S
açık bir arabirim üyesi uygulamasının bildiriminiI
içeriyorsa, bu üye uygulamasıdırM
.I.M
- Aksi takdirde, ile eşleşen
S
statik olmayan bir ortak üyenin bildiriminiM
içeriyorsa, bu üye uygulamasıdırI.M
. Birden fazla üye eşleşirse, hangi üyeninI.M
uygulaması olduğu belirtilmez. Bu durum yalnızca, genel türde bildirilen iki üyenin farklı imzalara sahip olduğu, ancak tür bağımsız değişkenlerinin imzalarını özdeş hale getirmesi durumunda ortaya çıkabilirS
.
uygulamasının temel sınıf listesinde C
belirtilen tüm arabirimlerin tüm üyeleri için uygulamalar bulunamazsa derleme zamanı hatası oluşur. Bir arabirimin üyeleri, temel arabirimlerden devralınan üyeleri içerir.
Yapılandırılmış arabirim türünün üyeleri, §15.3.3'te belirtilen karşılık gelen tür bağımsız değişkenleriyle değiştirilen herhangi bir tür parametresine sahip olarak kabul edilir.
Örnek: Örneğin, genel arabirim bildirimi göz önünde bulundurulduğunda:
interface I<T> { T F(int x, T[,] y); T this[int y] { get; } }
oluşturulan arabirimde
I<string[]>
şu üyeler bulunur:string[] F(int x, string[,][] y); string[] this[int y] { get; }
son örnek
Arabirim eşleme amacıyla, bir sınıf veya yapı üyesi A
aşağıdaki durumlarda arabirim üyesiyle B
eşleşir:
-
A
veB
yöntemleridir ve ve'ninA
B
adı, türü ve parametre listeleri aynıdır. -
A
veB
özellikleridir, adı ve türüA
B
aynıdır veA
ile aynı erişimcilereB
sahiptir (A
açık bir arabirim üyesi uygulaması değilse ek erişimcilere izin verilir). -
A
veB
olayları, adı ve türüA
ileB
aynıdır. -
A
veB
dizin oluşturucularıdır, türü ve parametre listeleriA
B
aynıdır veA
(B
açık bir arabirim üyesi uygulaması değilse ek erişimcilere sahip olması için izin verilir) ile aynı erişimcilereA
sahiptir.
Arabirim eşleme algoritmasının önemli etkileri şunlardır:
- Açık arabirim üyesi uygulamaları, bir arabirim üyesi uygulayan sınıf veya yapı üyesini belirlerken aynı sınıf veya yapıdaki diğer üyelere göre önceliklidir.
- Genel olmayan veya statik üyeler arabirim eşlemeye katılmaz.
Örnek: Aşağıdaki kodda
interface ICloneable { object Clone(); } class C : ICloneable { object ICloneable.Clone() {...} public object Clone() {...} }
ICloneable.Clone
açık arabirim üyesi uygulamaları diğer üyelere göre öncelikli olduğundan öğesininC
üyesi 'ICloneable' içinde uygulamasıClone
olur.son örnek
Bir sınıf veya yapı aynı ad, tür ve parametre türlerine sahip bir üye içeren iki veya daha fazla arabirim uygularsa, bu arabirim üyelerinin her birini tek bir sınıf veya yapı üyesine eşlemek mümkündür.
Örnek:
interface IControl { void Paint(); } interface IForm { void Paint(); } class Page : IControl, IForm { public void Paint() {...} }
Burada,
Paint
hem veIControl
IForm
yöntemleri içindekiPaint
yönteminePage
eşlenir. Elbette iki yöntem için ayrı açık arabirim üyesi uygulamalarına sahip olmak da mümkündür.son örnek
Bir sınıf veya yapı gizli üyeleri içeren bir arabirim uygularsa, bazı üyelerin açık arabirim üyesi uygulamaları aracılığıyla uygulanması gerekebilir.
Örnek:
interface IBase { int P { get; } } interface IDerived : IBase { new int P(); }
Bu arabirimin uygulanması için en az bir açık arabirim üyesi uygulaması gerekir ve aşağıdaki formlardan birini alır
class C1 : IDerived { int IBase.P { get; } int IDerived.P() {...} } class C2 : IDerived { public int P { get; } int IDerived.P() {...} } class C3 : IDerived { int IBase.P { get; } public int P() {...} }
son örnek
Bir sınıf aynı temel arabirime sahip birden çok arabirim uyguladığında, temel arabirimin yalnızca bir uygulaması olabilir.
Örnek: Aşağıdaki kodda
interface IControl { void Paint(); } interface ITextBox : IControl { void SetText(string text); } interface IListBox : IControl { void SetItems(string[] items); } class ComboBox : IControl, ITextBox, IListBox { void IControl.Paint() {...} void ITextBox.SetText(string text) {...} void IListBox.SetItems(string[] items) {...} }
temel sınıf listesinde adlı, tarafından devralınan
IControl
veIControl
tarafından devralınanITextBox
IControl
için ayrı uygulamaları olması mümkünIListBox
değildir. Aslında, bu arabirimler için ayrı bir kimlik diye bir şey yoktur. Bunun yerine, uygulamalarıITextBox
veIListBox
ile aynı uygulamasınıIControl
paylaşır veComboBox
yalnızca ,IControl
veITextBox
olmak üzere üç arabirimIListBox
uygulamak için kabul edilir.son örnek
Bir temel sınıfın üyeleri arabirim eşlemesine katılır.
Örnek: Aşağıdaki kodda
interface Interface1 { void F(); } class Class1 { public void F() {} public void G() {} } class Class2 : Class1, Interface1 { public new void G() {} }
yöntemi
F
Class1
, uygulamasındaClass2's
kullanılırInterface1
.son örnek
18.6.6 Arabirim uygulaması devralma
Bir sınıf, temel sınıfları tarafından sağlanan tüm arabirim uygulamalarını devralır.
Bir arabirimi açıkça yeniden uygulamadan türetilmiş bir sınıf, temel sınıflarından devraldığı arabirim eşlemelerini hiçbir şekilde değiştiremez.
Örnek: Bildirimlerde
interface IControl { void Paint(); } class Control : IControl { public void Paint() {...} } class TextBox : Control { public new void Paint() {...} }
Paint
içindeki yöntemiTextBox
içindekiPaint
yöntemini gizlerControl
, ancak öğesinin eşlemesiniControl.Paint
IControl.Paint
değiştirmez ve sınıf örnekleri ve arabirim örnekleri aracılığıyla çağrısınınPaint
aşağıdaki etkileri olacaktırControl c = new Control(); TextBox t = new TextBox(); IControl ic = c; IControl it = t; c.Paint(); // invokes Control.Paint(); t.Paint(); // invokes TextBox.Paint(); ic.Paint(); // invokes Control.Paint(); it.Paint(); // invokes Control.Paint();
son örnek
Ancak, bir arabirim yöntemi bir sınıftaki bir sanal yönteme eşlendiğinde, türetilmiş sınıfların sanal yöntemi geçersiz kılıp arabirimin uygulamasını değiştirmesi mümkündür.
Örnek: Yukarıdaki bildirimleri yeniden yazma
interface IControl { void Paint(); } class Control : IControl { public virtual void Paint() {...} } class TextBox : Control { public override void Paint() {...} }
şimdi aşağıdaki etkiler gözlemlenecektir
Control c = new Control(); TextBox t = new TextBox(); IControl ic = c; IControl it = t; c.Paint(); // invokes Control.Paint(); t.Paint(); // invokes TextBox.Paint(); ic.Paint(); // invokes Control.Paint(); it.Paint(); // invokes TextBox.Paint();
son örnek
Açık arabirim üyesi uygulamaları sanal olarak bildirilemediğinden, açık arabirim üyesi uygulamasını geçersiz kılmak mümkün değildir. Ancak, açık arabirim üyesi uygulamasının başka bir yöntemi çağırması ve türetilmiş sınıfların bunu geçersiz kılması için diğer yöntemin sanal olarak bildirilmesi mükemmel bir şekilde geçerlidir.
Örnek:
interface IControl { void Paint(); } class Control : IControl { void IControl.Paint() { PaintControl(); } protected virtual void PaintControl() {...} } class TextBox : Control { protected override void PaintControl() {...} }
Burada, 'den
Control
türetilen sınıflar yöntemini geçersiz kılarakIControl.Paint
uygulamasınıPaintControl
özelleştirebilir.son örnek
18.6.7 Arabirimi yeniden uygulama
Arabirim uygulamasını devralan bir sınıfın, temel sınıf listesine ekleyerek arabirimi yeniden uygulamasına izin verilir.
Bir arabirimin yeniden uygulanması, bir arabirimin ilk uygulamasıyla tam olarak aynı arabirim eşleme kurallarını izler. Bu nedenle, devralınan arabirim eşlemesinin arabirimin yeniden uygulanması için oluşturulan arabirim eşlemesi üzerinde hiçbir etkisi yoktur.
Örnek: Bildirimlerde
interface IControl { void Paint(); } class Control : IControl { void IControl.Paint() {...} } class MyControl : Control, IControl { public void Paint() {} }
'a eşlendiği
Control
IControl.Paint
Control.IControl.Paint
gerçeği, ile eşlenenMyControl
IControl.Paint
içindekiMyControl.Paint
yeniden uygulamayı etkilemez.son örnek
Devralınan genel üye bildirimleri ve devralınan açık arabirim üyesi bildirimleri, yeniden uygulanan arabirimler için arabirim eşleme işlemine katılır.
Örnek:
interface IMethods { void F(); void G(); void H(); void I(); } class Base : IMethods { void IMethods.F() {} void IMethods.G() {} public void H() {} public void I() {} } class Derived : Base, IMethods { public void F() {} void IMethods.H() {} }
Burada, uygulamasında uygulaması
IMethods
Derived
arabirim yöntemlerini , ,Derived.F
Base.IMethods.G
veDerived.IMethods.H
ileBase.I
eşler.son örnek
Bir sınıf bir arabirim uyguladığında, örtük olarak bu arabirimin tüm temel arabirimlerini de uygular. Benzer şekilde, bir arabirimin yeniden uygulanması da örtük olarak arabirimin tüm temel arabirimlerinin yeniden uygulanmasıdır.
Örnek:
interface IBase { void F(); } interface IDerived : IBase { void G(); } class C : IDerived { void IBase.F() {...} void IDerived.G() {...} } class D : C, IDerived { public void F() {...} public void G() {...} }
Burada, öğesinin yeniden uygulanması
IDerived
ile eşlemeyiIBase
IBase.F
de yeniden uygularD.F
.son örnek
18.6.8 Soyut sınıflar ve arabirimler
Soyut olmayan bir sınıf gibi, soyut sınıf da sınıfın temel sınıf listesinde listelenen arabirimlerin tüm üyelerinin uygulamalarını sağlayacaktır. Ancak, soyut bir sınıfın arabirim yöntemlerini soyut yöntemlerle eşlemesine izin verilir.
Örnek:
interface IMethods { void F(); void G(); } abstract class C : IMethods { public abstract void F(); public abstract void G(); }
Burada, haritaların
IMethods
veF
soyut yöntemlerinG
üzerine uygulanması, 'denC
türetilen soyut olmayan sınıflarda geçersiz kılınacaktır.son örnek
Açık arabirim üyesi uygulamaları soyut olamaz, ancak açık arabirim üyesi uygulamalarının soyut yöntemleri çağırmasına elbette izin verilir.
Örnek:
interface IMethods { void F(); void G(); } abstract class C: IMethods { void IMethods.F() { FF(); } void IMethods.G() { GG(); } protected abstract void FF(); protected abstract void GG(); }
Burada, ve
C
öğesini geçersiz kılmakFF
GG
için soyut olmayan sınıflar gerekli olur ve böylece gerçek uygulamasınıIMethods
sağlar.son örnek
ECMA C# draft specification