Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu bölüm, Microsoft Visual Basic dilinin semantiğini anlamak için gereken çeşitli kavramları kapsar. Kavramların çoğu Visual Basic programcıları veya C/C++ programcıları hakkında bilgi sahibi olmalıdır, ancak kesin tanımları farklı olabilir.
Bildirim
Visual Basic programı adlandırılmış varlıklardan oluşur. Bu varlıklar bildirimler aracılığıyla tanıtılır ve programın "anlamını" temsil eder.
En üst düzeyde, ad alanları iç içe ad alanları ve türler gibi diğer varlıkları düzenleyen varlıklardır. Türler , değerleri açıklayan ve yürütülebilir kod tanımlayan varlıklardır. Türler iç içe türler ve tür üyeleri içerebilir. Tür üyeleri sabitler, değişkenler, yöntemler, işleçler, özellikler, olaylar, numaralandırma değerleri ve oluşturuculardır.
Diğer varlıkları içerebilen bir varlık bir bildirim alanı tanımlar. Varlıklar, bildirimler veya devralma yoluyla bir bildirim alanına eklenir; içeren bildirim alanı, varlıkların bildirim bağlamı olarak adlandırılır. Bildirim alanında bir varlığın bildirim alanına bildirilmesi, daha fazla iç içe varlık bildirimi içerebilen yeni bir bildirim alanı tanımlar; bu nedenle, bir programdaki bildirimler bir bildirim alanları hiyerarşisi oluşturur.
Aşırı yüklenmiş tür üyeleri dışında, bildirimlerin aynı türdeki aynı adlandırılmış varlıkları aynı bildirim bağlamına eklemesi geçersizdir. Ayrıca, bir bildirim alanı hiçbir zaman aynı ada sahip farklı türde varlıklar içermeyebilir; örneğin, bildirim alanı hiçbir zaman aynı ada sahip bir değişken ve yöntem içermeyebilir.
Not. Diğer dillerde aynı ada sahip farklı türde varlıklar içeren bir bildirim alanı oluşturmak mümkün olabilir (örneğin, dil büyük/küçük harfe duyarlıysa ve büyük/küçük harfe göre farklı bildirimlere izin veriyorsa). Bu durumda, en erişilebilir varlık bu ada bağlı olarak kabul edilir; birden fazla varlık türü en erişilebilir durumdaysa ad belirsizdir.
Public, değerinden Protected Frienddaha erişilebilir, veya Frienddeğerinden Protected daha erişilebilir ve Protected veya Friend değerinden Privatedaha Protected Friend erişilebilir.
Bir ad alanının bildirim alanı "açık uçlu" olduğundan, aynı tam ada sahip iki ad alanı bildirimi aynı bildirim alanına katkıda bulunur. Aşağıdaki örnekte, iki ad alanı bildirimi aynı bildirim alanına katkıda bulunur, bu durumda tam adlara Data.Customer ve Data.Order:
Namespace Data
Class Customer
End Class
End Namespace
Namespace Data
Class Order
End Class
End Namespace
İki bildirim aynı bildirim alanına katkıda bulunduğundan, her biri aynı ada sahip bir sınıfın bildirimini içeriyorsa derleme zamanı hatası oluşur.
Aşırı Yükleme ve İmzalar
Bildirim alanında aynı türdeki aynı adlandırılmış varlıkları bildirmenin tek yolu aşırı yükleme yapmaktır. Yalnızca yöntemler, işleçler, örnek oluşturucuları ve özellikler aşırı yüklenebilir.
Aşırı yüklenmiş tür üyeleri benzersiz imzalara sahip olmalıdır. Tür üyesinin imzası, tür parametrelerinin sayısından ve üyenin parametrelerinin sayısından ve türlerinden oluşur. Dönüştürme işleçleri, işlecin dönüş türünü de imzaya ekler.
Aşağıdakiler üyenin imzasının bir parçası değildir ve bu nedenle üzerinde aşırı yüklenemez:
Tür üyesine değiştiriciler (örneğin,
SharedveyaPrivate).Bir parametrenin değiştiricileri (örneğin,
ByValveyaByRef).Parametrelerin adları.
Bir yöntemin veya işlecin dönüş türü (dönüştürme işleçleri hariç) veya bir özelliğin öğe türü.
Tür parametresindeki kısıtlamalar.
Aşağıdaki örnekte, imzalarıyla birlikte aşırı yüklenmiş yöntem bildirimleri kümesi gösterilmektedir. Yöntem bildirimlerinden birkaçı aynı imzalara sahip olduğundan bu bildirim geçerli olmayacaktır.
Interface ITest
Sub F1() ' Signature is ().
Sub F2(x As Integer) ' Signature is (Integer).
Sub F3(ByRef x As Integer) ' Signature is (Integer).
Sub F4(x As Integer, y As Integer) ' Signature is (Integer, Integer).
Function F5(s As String) As Integer ' Signature is (String).
Function F6(x As Integer) As Integer ' Signature is (Integer).
Sub F7(a() As String) ' Signature is (String()).
Sub F8(ParamArray a() As String) ' Signature is (String()).
Sub F9(Of T)() ' Signature is !1().
Sub F10(Of T, U)(x As T, y As U) ' Signature is !2(!1, !2)
Sub F11(Of U, T)(x As T, y As U) ' Signature is !2(!2, !1)
Sub F12(Of T)(x As T) ' Signature is !1(!1)
Sub F13(Of T As IDisposable)(x As T) ' Signature is !1(!1)
End Interface
Sağlanan tür bağımsız değişkenlerine göre aynı imzalara sahip üyeler içerebilecek genel bir tür tanımlamak geçerlidir. Aşırı yükleme çözümleme kuralları, bu tür aşırı yüklemeler arasında ayrım yapmak için kullanılır, ancak kesinleştirmenin imkansız olduğu durumlar olabilir. Örneğin:
Class C(Of T)
Sub F(x As Integer)
End Sub
Sub F(x As T)
End Sub
Sub G(Of U)(x As T, y As U)
End Sub
Sub G(Of U)(x As U, y As T)
End Sub
End Class
Module Test
Sub Main()
Dim x As New C(Of Integer)
x.F(10) ' Calls C(Of T).F(Integer)
x.G(Of Integer)(10, 10) ' Error: Can't choose between overloads
End Sub
End Module
Scope
Bir varlığın adının kapsamı , niteleme olmadan bu ada başvurmanın mümkün olduğu tüm bildirim alanları kümesidir. Genel olarak, bir varlığın adının kapsamı, bildirim bağlamının tamamıdır; ancak, bir varlığın bildirimi aynı ada sahip varlıkların iç içe bildirimleri içerebilir. Bu durumda iç içe geçmiş varlık dış varlığı gölgeler veya gizler ve gölgeli varlığa erişim yalnızca niteleme yoluyla mümkündür.
İç içe geçme yoluyla gölgeleme, ad alanları içinde iç içe geçmiş ad alanları veya türlerde, diğer türlerin içinde iç içe yerleştirilmiş türlerde ve tür üyelerinin gövdelerinde gerçekleşir. Bildirimlerin iç içe geçme işleminin gölgelenmesi her zaman örtük olarak gerçekleşir; açık söz dizimi gerekmez.
Aşağıdaki örnekte, yönteminin F içinde, örnek değişkeni i yerel değişkeni itarafından gölgelenmiştir, ancak yöntemin Gi içinde yine de örnek değişkenine başvurur.
Class Test
Private i As Integer = 0
Sub F()
Dim i As Integer = 1
End Sub
Sub G()
i = 1
End Sub
End Class
İç kapsamdaki bir ad dış kapsamdaki bir adı gizlediğinde, bu adın aşırı yüklenmiş tüm oluşumlarını gölgeler. Aşağıdaki örnekte çağrısı, F(1) içinde bildirilen Inner öğesini F çağırır çünkü tüm dış oluşumları F iç bildirim tarafından gizlenir. Aynı nedenle, çağrı F("Hello") hatalıdır.
Class Outer
Shared Sub F(i As Integer)
End Sub
Shared Sub F(s As String)
End Sub
Class Inner
Shared Sub F(l As Long)
End Sub
Sub G()
F(1) ' Invokes Outer.Inner.F.
F("Hello") ' Error.
End Sub
End Class
End Class
Inheritance
Devralma ilişkisi, türetilen türün bildirim alanı örtük olarak erişilebilir oluşturucu olmayan tür üyelerini ve temel türünün iç içe türlerini içerecek şekilde bir türün (türetilmiş tür) başka bir türden (temel tür) türetildiği ilişkidir. Aşağıdaki örnekte, sınıfı A temel sınıfıdır Bve B öğesinden Atüretilmiştir.
Class A
End Class
Class B
Inherits A
End Class
A Açıkça bir temel sınıf belirtmediğinden, temel sınıfı örtük olarak Objectolur.
Devralma işleminin önemli yönleri şunlardır:
Devralma geçişli. C türü B türünden türetilirse ve B türü A türünden türetilirse, C türü B türünde bildirilen tür üyelerini ve A türünde bildirilen tür üyelerini devralır.
Türetilmiş bir tür, temel türünü genişletir ancak daraltamaz. Türetilmiş bir tür yeni tür üyeleri ekleyebilir ve devralınan tür üyelerini gölgeleyebilir, ancak devralınan tür üyesinin tanımını kaldıramaz.
Bir türün örneği, temel türünün tüm tür üyelerini içerdiğinden, türetilmiş bir türden temel türüne dönüştürme her zaman vardır.
türü dışında tüm türlerin bir temel türü
Objectolmalıdır. Bu nedenle,Objecttüm türlerin nihai temel türüdür ve tüm türler buna dönüştürülebilir.Türetmede döngüselliğe izin verilmez. Yani, bir tür
BtüründenAtüretildiğinde, türündenAdoğrudan veya dolaylı olarakBtüretilen bir hatadır.Bir tür, doğrudan veya dolaylı olarak içinde iç içe yerleştirilmiş bir türden türetilmeyebilir.
Aşağıdaki örnek, sınıflar döngüsel olarak birbirine bağlı olduğundan derleme zamanı hatası oluşturur.
Class A
Inherits B
End Class
Class B
Inherits C
End Class
Class C
Inherits A
End Class
Aşağıdaki örnek, dolaylı olarak sınıfı aracılığıyla Aiç içe geçmiş sınıfından C türetildiği için B bir derleme zamanı hatası da oluşturur.
Class A
Inherits B.C
End Class
Class B
Inherits A
Public Class C
End Class
End Class
Sonraki örnek, sınıfından ABtüretilmediğinden hata üretmez.
Class A
Class B
Inherits A
End Class
End Class
MustInherit ve NotInheritable Sınıfları
Sınıf MustInherit , yalnızca temel tür olarak davranabilen tamamlanmamış bir türdür. Bir MustInherit sınıf örneği oluşturulamadığından, işlecinin bir tanesinde New kullanılması bir hatadır. Sınıfların MustInherit değişkenlerini bildirmek geçerlidir; bu tür değişkenler yalnızca atanabilir Nothing veya sınıfından türetilen bir sınıftan MustInherit gelen bir değer olabilir.
Normal bir sınıf bir MustInherit sınıftan türetildiğinde, normal sınıfın devralınan MustOverride tüm üyeleri geçersiz kılmalıdır. Örneğin:
MustInherit Class A
Public MustOverride Sub F()
End Class
MustInherit Class B
Inherits A
Public Sub G()
End Sub
End Class
Class C
Inherits B
Public Overrides Sub F()
End Sub
End Class
MustInherit sınıfı A bir MustOverride yöntemi Ftanıtır. Sınıfı B ek bir yöntemi Gtanıtır, ancak uygulamasını Fsağlamaz. Bu nedenle sınıfı B da bildirilmelidir MustInherit. Sınıf C geçersiz kılar F ve gerçek bir uygulama sağlar. sınıfında Cbekleyen MustOverride üye olmadığından olması gerekmezMustInherit.
Sınıf NotInheritable , başka bir sınıfın türetilemediği bir sınıftır.
NotInheritable sınıflar öncelikli olarak istenmeyen türetme önlemek için kullanılır.
Bu örnekte sınıfından B türetmeye çalıştığından NotInheritable sınıfı Ahatalıdır. Bir sınıf hem hem de MustInheritNotInheritableolarak işaretlenemez.
NotInheritable Class A
End Class
Class B
' Error, a class cannot derive from a NotInheritable class.
Inherits A
End Class
Arabirimler ve Birden Çok Devralma
Yalnızca tek bir temel türden türetilen diğer türlerden farklı olarak, bir arabirim birden çok temel arabirimden türetilebilir. Bu nedenle, bir arabirim farklı temel arabirimlerden aynı adlı tür üyesini devralabilir. Böyle bir durumda, çarpma devralınan ad türetilmiş arabirimde kullanılamaz ve türetilmiş arabirim aracılığıyla bu tür üyelerin herhangi birine başvurmak, imzalardan veya aşırı yüklemeden bağımsız olarak derleme zamanı hatasına neden olur. Bunun yerine, çakışan tür üyelerine bir temel arabirim adı üzerinden başvurulmalıdır.
Aşağıdaki örnekte, çarpma devralınan üye Count arabiriminde IListCounterkullanılamadığından ilk iki deyim derleme zamanı hatalarına neden olur:
Interface IList
Property Count() As Integer
End Interface
Interface ICounter
Sub Count(i As Integer)
End Interface
Interface IListCounter
Inherits IList
Inherits ICounter
End Interface
Module Test
Sub F(x As IListCounter)
x.Count(1) ' Error, Count is not available.
x.Count = 1 ' Error, Count is not available.
CType(x, IList).Count = 1 ' Ok, invokes IList.Count.
CType(x, ICounter).Count(1) ' Ok, invokes ICounter.Count.
End Sub
End Module
Örnekte gösterildiği gibi belirsizlik, uygun temel arabirim türüne geçirilerek x çözümlenir. Bu tür atamaların çalışma zamanı maliyeti yoktur; yalnızca derleme zamanında örneği daha az türetilmiş bir tür olarak görüntülemektir.
Tek bir tür üyesi birden çok yol aracılığıyla aynı temel arabirimden devralındığında, tür üyesi yalnızca bir kez devralınmış gibi kabul edilir. Başka bir deyişle, türetilmiş arabirim, belirli bir temel arabirimden devralınan her tür üyesinin yalnızca bir örneğini içerir. Örneğin:
Interface IBase
Sub F(i As Integer)
End Interface
Interface ILeft
Inherits IBase
End Interface
Interface IRight
Inherits IBase
End Interface
Interface IDerived
Inherits ILeft, IRight
End Interface
Class Derived
Implements IDerived
' Only have to implement F once.
Sub F(i As Integer) Implements IDerived.F
End Sub
End Class
Tür üyesi adı, devralma hiyerarşisi aracılığıyla bir yolda gölgeliyse, ad tüm yollarda gölgeli olur. Aşağıdaki örnekte, IBase.F üye üye tarafından ILeft.F gölgelenmiştir, ancak içinde IRightgölgelenmez:
Interface IBase
Sub F(i As Integer)
End Interface
Interface ILeft
Inherits IBase
Shadows Sub F(i As Integer)
End Interface
Interface IRight
Inherits IBase
Sub G()
End Interface
Interface IDerived
Inherits ILeft, IRight
End Interface
Class Test
Sub H(d As IDerived)
d.F(1) ' Invokes ILeft.F.
CType(d, IBase).F(1) ' Invokes IBase.F.
CType(d, ILeft).F(1) ' Invokes ILeft.F.
CType(d, IRight).F(1) ' Invokes IBase.F.
End Sub
End Class
Çağrıd.F(1), üzerinden geçen IRighterişim yolunda gölgelenmemiş gibi görünse IBase.F de öğesini seçerILeft.F. öğesinden gölgelere ILeftIBase.FIBase erişim yolu olduğundan, öğesinden IDerivedIDerivedIRightIBaseöğesine erişim yolunda da üye gölgeli durumdadır.
Gölgeleme
Türetilmiş tür, devralınan bir tür üyesinin adını yeniden bildirerek gölgeler. Bir adı gölgelendirmek, bu ada sahip devralınan tür üyelerini kaldırmaz; yalnızca bu ada sahip devralınan tüm tür üyelerini türetilmiş sınıfta kullanılamaz hale getirir. Gölgeleme bildirimi herhangi bir varlık türü olabilir.
Fazla yüklenebilen varlıklar, iki gölgelendirme biçiminden birini seçebilir.
Ada göre gölgeleme anahtar sözcüğü kullanılarak Shadows belirtilir. Ada göre gölgeleyen bir varlık, tüm aşırı yüklemeler dahil olmak üzere temel sınıftaki her şeyi bu ada göre gizler.
Ada ve imzayaOverloads göre gölgelendirme anahtar sözcüğü kullanılarak belirtilir. Ada ve imzaya göre gölgeleyen bir varlık, varlıkla aynı imzaya sahip her şeyi bu ada göre gizler. Örneğin:
Class Base
Sub F()
End Sub
Sub F(i As Integer)
End Sub
Sub G()
End Sub
Sub G(i As Integer)
End Sub
End Class
Class Derived
Inherits Base
' Only hides F(Integer).
Overloads Sub F(i As Integer)
End Sub
' Hides G() and G(Integer).
Shadows Sub G(i As Integer)
End Sub
End Class
Module Test
Sub Main()
Dim x As New Derived()
x.F() ' Calls Base.F().
x.G() ' Error: Missing parameter.
End Sub
End Module
Bir yöntemi ad ve imzaya göre bağımsız ParamArray değişkenle gölgelendirmek, tüm olası genişletilmiş imzaları değil, yalnızca tek tek imzayı gizler. Gölgeleme yönteminin imzası, gölgeli yöntemin genişletilmemiş imzası ile eşleşse bile bu doğrudur. Aşağıdaki örnek:
Class Base
Sub F(ParamArray x() As Integer)
Console.WriteLine("Base")
End Sub
End Class
Class Derived
Inherits Base
Overloads Sub F(x() As Integer)
Console.WriteLine("Derived")
End Sub
End Class
Module Test
Sub Main
Dim d As New Derived()
d.F(10)
End Sub
End Module
Base, genişletilmemiş biçimiyle Base.Faynı imzaya sahip olsa Derived.F da yazdırır.
Buna karşılık, bağımsız değişkeni olan bir ParamArray yöntem, tüm olası genişletilmiş imzaları değil, yalnızca aynı imzaya sahip yöntemleri gölgeler. Aşağıdaki örnek:
Class Base
Sub F(x As Integer)
Console.WriteLine("Base")
End Sub
End Class
Class Derived
Inherits Base
Overloads Sub F(ParamArray x() As Integer)
Console.WriteLine("Derived")
End Sub
End Class
Module Test
Sub Main()
Dim d As New Derived()
d.F(10)
End Sub
End Module
Baseile aynı imzaya Base.Fsahip genişletilmiş bir forma sahip olsa Derived.F bile yazdırır.
Yöntemin veya özelliğin bildirilip bildirilmediğini ShadowsOverridesbelirtmeyen Shadows veya Overloads varsaymayan Overloads bir gölgeleme yöntemi veya özelliği aksi takdirde. Aşırı yüklenmiş bir varlık kümesinin bir üyesi veya Overloads anahtar sözcüğünü belirtirse, tümünün Shadows bunu belirtmesi gerekir.
Shadows ve Overloads anahtar sözcükleri aynı anda belirtilemez. Standart Shadows modülde ne belirtilebilir ne de Overloads belirtilebilir; standart modüldeki üyeler örtük olarak öğesinden devralınan Objectgölge üyelerdir.
Arabirim devralma yoluyla çarpma-devralınan (ve dolayısıyla kullanılamaz) bir tür üyesinin adını gölgelendirmek ve bu nedenle adı türetilen arabirimde kullanılabilir hale getirmek için geçerlidir.
Örneğin:
Interface ILeft
Sub F()
End Interface
Interface IRight
Sub F()
End Interface
Interface ILeftRight
Inherits ILeft, IRight
Shadows Sub F()
End Interface
Module Test
Sub G(i As ILeftRight)
i.F() ' Calls ILeftRight.F.
CType(i, ILeft).F() ' Calls ILeft.F.
CType(i, IRight).F() ' Calls IRight.F.
End Sub
End Module
Yöntemlerin devralınan yöntemleri gölgelendirmesine izin verildiğinden, sınıfın aynı imzaya sahip birkaç Overridable yöntem içermesi mümkündür. Yalnızca en çok türetilen yöntem görünür olduğundan bu bir belirsizlik sorunu sunmaz. Aşağıdaki örnekte ve D sınıfları aynı C imzaya sahip iki Overridable yöntem içerir:
Class A
Public Overridable Sub F()
Console.WriteLine("A.F")
End Sub
End Class
Class B
Inherits A
Public Overrides Sub F()
Console.WriteLine("B.F")
End Sub
End Class
Class C
Inherits B
Public Shadows Overridable Sub F()
Console.WriteLine("C.F")
End Sub
End Class
Class D
Inherits C
Public Overrides Sub F()
Console.WriteLine("D.F")
End Sub
End Class
Module Test
Sub Main()
Dim d As New D()
Dim a As A = d
Dim b As B = d
Dim c As C = d
a.F()
b.F()
c.F()
d.F()
End Sub
End Module
Burada iki Overridable yöntem vardır: biri sınıfı A tarafından tanıtılan, diğeri de sınıfı Ctarafından tanıtılan yöntem. sınıfı C tarafından sunulan yöntem, sınıfından Adevralınan yöntemi gizler. Bu nedenle, sınıfındaki OverridesD bildirimi, sınıfı Ctarafından tanıtılan yöntemi geçersiz kılar ve sınıfı D tarafından Atanıtılan yöntemi geçersiz kılmak mümkün değildir. Örnek çıkışı oluşturur:
B.F
B.F
D.F
D.F
Gizli yöntemi, gizli olmayan daha az türetilmiş bir tür aracılığıyla sınıfın D bir örneğine erişerek çağırmak Overridable mümkündür.
Çoğu durumda sınıfı kullanılamaz hale getireceğinden, yöntemi MustOverride gölgelendirmek geçerli değildir. Örneğin:
MustInherit Class Base
Public MustOverride Sub F()
End Class
MustInherit Class Derived
Inherits Base
Public Shadows Sub F()
End Sub
End Class
Class MoreDerived
Inherits Derived
' Error: MustOverride method Base.F is not overridden.
End Class
Bu durumda, sınıfı MoreDerived yöntemini geçersiz kılmak MustOverride için gereklidir, ancak sınıfı Derived gölgelendiğinden Base.FBase.Fbu mümkün değildir. geçerli bir alt öğesini bildirmenin Derivedbir yolu yoktur.
Dış kapsamdaki bir adı gölgelendirmenin aksine, devralınan kapsamdan erişilebilir bir adı gölgelendirmek, aşağıdaki örnekte olduğu gibi bir uyarının bildirilmesine neden olur:
Class Base
Public Sub F()
End Sub
Private Sub G()
End Sub
End Class
Class Derived
Inherits Base
Public Sub F() ' Warning: shadowing an inherited name.
End Sub
Public Sub G() ' No warning, Base.G is not accessible here.
End Sub
End Class
sınıfında Derived yönteminin F bildirimi, bir uyarının bildirilmesine neden olur. Devralınan bir adı gölgelendirmek özellikle hata değildir, çünkü bu temel sınıfların ayrı evrimini ortadan kaldırır. Örneğin, sınıfın daha sonraki bir sürümünde sınıfının Base önceki bir sürümünde mevcut olmayan bir yöntem F sunulduğundan yukarıdaki durum ortaya çıkabilirdi. Yukarıdaki durum bir hata olsaydı, ayrı bir sürüme sahip sınıf kitaplığındaki bir temel sınıfta yapılan herhangi bir değişiklik türetilmiş sınıfların geçersiz olmasına neden olabilir.
Devralınan bir adı gölgelendirmenin neden olduğu uyarı, veya Overloads değiştiricisi Shadows kullanımıyla ortadan kaldırılabilir:
Class Base
Public Sub F()
End Sub
End Class
Class Derived
Inherits Base
Public Shadows Sub F() 'OK.
End Sub
End Class
Değiştirici, Shadows devralınan üyeyi gölgelendirme amacını gösterir. Gölgelendirmek için bir tür üye adı yoksa veya Overloads değiştiricisini belirtmek Shadows bir hata değildir.
Yeni üye bildirimi, devralınan bir üyeyi aşağıdaki örnekte olduğu gibi yalnızca yeni üyenin kapsamında gölgeler:
Class Base
Public Shared Sub F()
End Sub
End Class
Class Derived
Inherits Base
Private Shared Shadows Sub F() ' Shadows Base.F in class Derived only.
End Sub
End Class
Class MoreDerived
Inherits Derived
Shared Sub G()
F() ' Invokes Base.F.
End Sub
End Class
Yukarıdaki örnekte, sınıfında yöntemi F bildirimi sınıfından Basedevralınan yöntemi F gölgeler, ancak sınıfındaki Derived yeni yöntemin F erişimi olduğundan Private kapsamı sınıfına MoreDerivedgenişletilmez.Derived Bu nedenle, F() içinde MoreDerived.G çağrısı geçerlidir ve Base.F'yi çağırır. Aşırı yüklenmiş tür üyeleri söz konusu olduğunda, aşırı yüklenmiş tür üyeleri kümesinin tamamı, gölgeleme amacıyla en uygun erişime sahipmiş gibi kabul edilir.
Class Base
Public Sub F()
End Sub
End Class
Class Derived
Inherits Base
Private Shadows Sub F()
End Sub
Public Shadows Sub F(i As Integer)
End Sub
End Class
Class MoreDerived
Inherits Derived
Public Sub G()
F() ' Error. No accessible member with this signature.
End Sub
End Class
Bu örnekte, içinde Derived bildirimi F() erişimle Private bildirilmiş olsa da, aşırı yüklenmiş F(Integer) erişimle Public bildirilir. Bu nedenle, gölgelendirme amacıyla, içindeki adı F olduğu gibi Publicdeğerlendirilir, bu nedenle her iki yöntem de içinde Basegölge FDerived alır.
Uygulama
Bir tür bir arabirim uyguladığını bildirdiğinde ve tür arabirimin tüm tür üyelerini uyguladığında bir uygulama ilişkisi vardır. Belirli bir arabirimi uygulayan bir tür, bu arabirime dönüştürülebilir. Arabirimlerin örneği oluşturulamaz, ancak arabirim değişkenlerini bildirmek geçerli olur; bu tür değişkenlere yalnızca arabirimini uygulayan bir sınıfın değeri atanabilir. Örneğin:
Interface ITestable
Function Test(value As Byte) As Boolean
End Interface
Class TestableClass
Implements ITestable
Function Test(value As Byte) As Boolean Implements ITestable.Test
Return value > 128
End Function
End Class
Module Test
Sub F()
Dim x As ITestable = New TestableClass
Dim b As Boolean
b = x.Test(34)
End Sub
End Module
Çarpma devralınan tür üyelerine sahip bir arabirim uygulayan bir tür, uygulanmakta olan türetilmiş arabirimden doğrudan erişilemese bile bu yöntemleri uygulamaya devam etmelidir. Örneğin:
Interface ILeft
Sub Test()
End Interface
Interface IRight
Sub Test()
End Interface
Interface ILeftRight
Inherits ILeft, IRight
End Interface
Class LeftRight
Implements ILeftRight
' Has to reference ILeft explicitly.
Sub TestLeft() Implements ILeft.Test
End Sub
' Has to reference IRight explicitly.
Sub TestRight() Implements IRight.Test
End Sub
' Error: Test is not available in ILeftRight.
Sub TestLeftRight() Implements ILeftRight.Test
End Sub
End Class
Sınıflar bile MustInherit uygulanan arabirimlerin tüm üyelerinin uygulamalarını sağlamalıdır; ancak, bunları olarak MustOverridebildirerek bu yöntemlerin uygulanmasını erteleyebilirler. Örneğin:
Interface ITest
Sub Test1()
Sub Test2()
End Interface
MustInherit Class TestBase
Implements ITest
' Provides an implementation.
Sub Test1() Implements ITest.Test1
End Sub
' Defers implementation.
MustOverride Sub Test2() Implements ITest.Test2
End Class
Class TestDerived
Inherits TestBase
' Have to implement MustOverride method.
Overrides Sub Test2()
End Sub
End Class
Bir tür, temel türünün uyguladığı bir arabirimi yeniden uygulamayı seçebilir. Arabirimi yeniden uygulamak için türün arabirimi uyguladığını açıkça belirtmesi gerekir. Bir arabirimi yeniden uygulayan bir tür, arabirimin üyelerinin yalnızca bazılarını yeniden uygulamayı seçebilir, ancak tümünü değil-- yeniden uygulanmayan tüm üyeler temel türün uygulamasını kullanmaya devam edebilir. Örneğin:
Class TestBase
Implements ITest
Sub Test1() Implements ITest.Test1
Console.WriteLine("TestBase.Test1")
End Sub
Sub Test2() Implements ITest.Test2
Console.WriteLine("TestBase.Test2")
End Sub
End Class
Class TestDerived
Inherits TestBase
Implements ITest ' Required to re-implement
Sub DerivedTest1() Implements ITest.Test1
Console.WriteLine("TestDerived.DerivedTest1")
End Sub
End Class
Module Test
Sub Main()
Dim Test As ITest = New TestDerived()
Test.Test1()
Test.Test2()
End Sub
End Module
Bu örnek şunu yazdırır:
TestDerived.DerivedTest1
TestBase.Test2
Türetilmiş bir tür, temel arabirimleri türetilmiş türün temel türleri tarafından uygulanan bir arabirim uyguladığında, türetilen tür yalnızca temel türler tarafından henüz uygulanmamış olan arabirimin tür üyelerini uygulamayı seçebilir. Örneğin:
Interface IBase
Sub Base()
End Interface
Interface IDerived
Inherits IBase
Sub Derived()
End Interface
Class Base
Implements IBase
Public Sub Base() Implements IBase.Base
End Sub
End Class
Class Derived
Inherits Base
Implements IDerived
' Required: IDerived.Derived not implemented by Base.
Public Sub Derived() Implements IDerived.Derived
End Sub
End Class
Arabirim yöntemi, temel türdeki geçersiz kılınabilir bir yöntem kullanılarak da uygulanabilir. Bu durumda, türetilmiş bir tür de geçersiz kılınabilir yöntemini geçersiz kılabilir ve arabirimin uygulamasını değiştirebilir. Örneğin:
Class Base
Implements ITest
Public Sub Test1() Implements ITest.Test1
Console.WriteLine("TestBase.Test1")
End Sub
Public Overridable Sub Test2() Implements ITest.Test2
Console.WriteLine("TestBase.Test2")
End Sub
End Class
Class Derived
Inherits Base
' Overrides base implementation.
Public Overrides Sub Test2()
Console.WriteLine("TestDerived.Test2")
End Sub
End Class
Yöntemleri Uygulama
Bir tür, bir yan tümcesi ile bir yöntem sağlayarak uygulanan arabirimin tür üyesini Implementsuygular. İki tür üyesi aynı sayıda parametreye sahip olmalıdır, isteğe bağlı parametrelerin varsayılan değeri de dahil olmak üzere parametrelerin tüm türleri ve değiştiricileri eşleşmelidir, dönüş türü eşleşmelidir ve yöntem parametrelerindeki kısıtlamaların tümü eşleşmelidir. Örneğin:
Interface ITest
Sub F(ByRef x As Integer)
Sub G(Optional y As Integer = 20)
Sub H(Paramarray z() As Integer)
End Interface
Class Test
Implements ITest
' Error: ByRef/ByVal mismatch.
Sub F(x As Integer) Implements ITest.F
End Sub
' Error: Defaults do not match.
Sub G(Optional y As Integer = 10) Implements ITest.G
End Sub
' Error: Paramarray does not match.
Sub H(z() As Integer) Implements ITest.H
End Sub
End Class
Tek bir yöntem, tümü yukarıdaki ölçütleri karşılıyorsa herhangi bir sayıda arabirim türü üyesi uygulayabilir. Örneğin:
Interface ITest
Sub F(i As Integer)
Sub G(i As Integer)
End Interface
Class Test
Implements ITest
Sub F(i As Integer) Implements ITest.F, ITest.G
End Sub
End Class
Bir yöntemi genel arabirimde uygularken, uygulayan yöntemin arabirimin tür parametrelerine karşılık gelen tür bağımsız değişkenlerini sağlaması gerekir. Örneğin:
Interface I1(Of U, V)
Sub M(x As U, y As List(Of V))
End Interface
Class C1(Of W, X)
Implements I1(Of W, X)
' W corresponds to U and X corresponds to V
Public Sub M(x As W, y As List(Of X)) Implements I1(Of W, X).M
End Sub
End Class
Class C2
Implements I1(Of String, Integer)
' String corresponds to U and Integer corresponds to V
Public Sub M(x As String, y As List(Of Integer)) _
Implements I1(Of String, Integer).M
End Sub
End Class
Genel bir arabirimin bazı tür bağımsız değişkenleri için uygulanamayabilir.
Interface I1(Of T, U)
Sub S1(x As T)
Sub S1(y As U)
End Interface
Class C1
' Unable to implement because I1.S1 has two identical signatures
Implements I1(Of Integer, Integer)
End Class
Çok biçimlilik
Polimorfizm , bir yöntemin veya özelliğin uygulanmasını değiştirebilme olanağı sağlar. Polimorfizm ile aynı yöntem veya özellik, onu çağıran örneğin çalışma zamanı türüne bağlı olarak farklı eylemler gerçekleştirebilir. Polimorfik yöntemler veya özellikler geçersiz kılınabilir olarak adlandırılır. Buna karşılık, geçersiz kılınamaz bir yöntem veya özelliğin uygulanması sabittir; yöntemi veya özelliği, bildirildiği sınıfın bir örneğinde veya türetilmiş bir sınıfın örneğinde çağrılırsa, uygulama aynıdır. Geçersiz kılınamaz bir yöntem veya özellik çağrıldığında, örneğin derleme zamanı türü belirleyici faktördür. Örneğin:
Class Base
Public Overridable Property X() As Integer
Get
End Get
Set
End Set
End Property
End Class
Class Derived
Inherits Base
Public Overrides Property X() As Integer
Get
End Get
Set
End Set
End Property
End Class
Module Test
Sub F()
Dim Z As Base
Z = New Base()
Z.X = 10 ' Calls Base.X
Z = New Derived()
Z.X = 10 ' Calls Derived.X
End Sub
End Module
Geçersiz kılınabilir bir yöntem de olabilir MustOverride. Bu, yöntem gövdesi sağlamadığı ve geçersiz kılınması gerektiği anlamına gelir.
MustOverride yöntemlerine yalnızca sınıflarda MustInherit izin verilir.
Aşağıdaki örnekte sınıfı Shape , kendisini boyayabilen geometrik şekil nesnesinin soyut tanımını tanımlar:
MustInherit Public Class Shape
Public MustOverride Sub Paint(g As Graphics, r As Rectangle)
End Class
Public Class Ellipse
Inherits Shape
Public Overrides Sub Paint(g As Graphics, r As Rectangle)
g.drawEllipse(r)
End Sub
End Class
Public Class Box
Inherits Shape
Public Overrides Sub Paint(g As Graphics, r As Rectangle)
g.drawRect(r)
End Sub
End Class
yönteminin PaintMustOverride nedeni, anlamlı bir varsayılan uygulama olmamasıdır.
Ellipse ve Box sınıfları somut Shape uygulamalardır. Bu sınıflar olmadığından MustInherit, yöntemini geçersiz kılmak Paint ve gerçek bir uygulama sağlamak için gereklidir.
Aşağıdaki örnekte gösterildiği gibi, temel erişimin bir MustOverride yönteme başvurması hatadır:
MustInherit Class A
Public MustOverride Sub F()
End Class
Class B
Inherits A
Public Overrides Sub F()
MyBase.F() ' Error, MyBase.F is MustOverride.
End Sub
End Class
Bir yönteme MyBase.F() başvuracağından çağrı için bir MustOverride hata bildirilir.
Yöntemleri Geçersiz Kılma
Bir tür, aynı ada ve , imzaya sahip bir yöntem bildirerek ve bildirimi değiştiriciyle işaretleyerek devralınan Overrides geçersiz kılınabilir bir yöntemi geçersiz kılabilir. Yöntemleri geçersiz kılmayla ilgili ek gereksinimler aşağıda listelenmiştir. Yöntem Overridable bildirimi yeni bir yöntem tanıtırken, Overrides yöntem bildirimi yöntemin devralınan uygulamasının yerini alır.
Geçersiz kılma yöntemi, türetilmiş türlerde yöntemin daha fazla geçersiz kılınmasını engelleyen olarak bildirilebilir NotOverridable. Aslında, NotOverridable yöntemler başka türetilmiş sınıflarda geçersiz kılınamaz hale gelir.
Aşağıdaki örneği göz önünde bulundurun:
Class A
Public Overridable Sub F()
Console.WriteLine("A.F")
End Sub
Public Overridable Sub G()
Console.WriteLine("A.G")
End Sub
End Class
Class B
Inherits A
Public Overrides NotOverridable Sub F()
Console.WriteLine("B.F")
End Sub
Public Overrides Sub G()
Console.WriteLine("B.G")
End Sub
End Class
Class C
Inherits B
Public Overrides Sub G()
Console.WriteLine("C.G")
End Sub
End Class
Örnekte, sınıfı B iki Overrides yöntem sağlar: değiştiricisi NotOverridable olan bir yöntem F ve olmayan bir yöntemG. Değiştiricinin NotOverridable kullanılması, sınıfının C yöntemini Fgeçersiz kılmasını engeller.
Geçersiz kılma yöntemi, geçersiz kılma yöntemi bildirilmemiş MustOverrideolsa bile olarak da bildirilebilir MustOverride. Bu, içeren sınıfın bildirilmesi MustInherit ve bildirilmeyen MustInherit diğer türetilmiş sınıfların yöntemini geçersiz kılması gerekir. Örneğin:
Class A
Public Overridable Sub F()
Console.WriteLine("A.F")
End Sub
End Class
MustInherit Class B
Inherits A
Public Overrides MustOverride Sub F()
End Class
Örnekte, sınıf B bir MustOverride yöntemle geçersiz kılarA.F. Bu, türetilen B tüm sınıfların da bildirilmediği MustInherit sürece öğesini geçersiz kılması Fgerekeceği anlamına gelir.
Geçersiz kılma yöntemi için aşağıdakilerin tümü doğru değilse derleme zamanı hatası oluşur:
- Bildirim bağlamı, geçersiz kılma yöntemiyle aynı imzaya ve dönüş türüne (varsa) sahip tek bir erişilebilir devralınan yöntem içerir.
- Geçersiz kılınan devralınan yöntem geçersiz kılınabilir. Başka bir deyişle, geçersiz kılınan devralınan yöntem veya
NotOverridabledeğildirShared. - Bildirilmekte olan yöntemin erişilebilirlik etki alanı, devralınan yöntemin geçersiz kılınan erişilebilirlik etki alanıyla aynıdır. Bir özel durum vardır:
Protected FriendDiğer yöntem geçersiz kılma yönteminin erişimi olmayanFriendbaşka birProtectedderlemedeyse yöntemin bir yöntem tarafından geçersiz kılınması gerekir. - Geçersiz kılma yönteminin parametreleri, isteğe bağlı parametreler için sağlanan değerler de dahil olmak üzere ,
ByRefParamArray,veOptionaldeğiştiricilerininByValkullanımıyla ilgili olarak geçersiz kılınan yöntemin parametreleriyle eşleşmektedir. - Geçersiz kılma yönteminin tür parametreleri, tür kısıtlamaları açısından geçersiz kılınan yöntemin tür parametreleriyle eşleşmektedir.
Temel genel türdeki bir yöntemi geçersiz kılma sırasında geçersiz kılma yöntemi, temel tür parametrelerine karşılık gelen tür bağımsız değişkenlerini sağlamalıdır. Örneğin:
Class Base(Of U, V)
Public Overridable Sub M(x As U, y As List(Of V))
End Sub
End Class
Class Derived(Of W, X)
Inherits Base(Of W, X)
' W corresponds to U and X corresponds to V
Public Overrides Sub M(x As W, y As List(Of X))
End Sub
End Class
Class MoreDerived
Inherits Derived(Of String, Integer)
' String corresponds to U and Integer corresponds to V
Public Overrides Sub M(x As String, y As List(Of Integer))
End Sub
End Class
Genel bir sınıfta geçersiz kılınabilir bir yöntemin bazı tür bağımsız değişken kümeleri için geçersiz kılınamayabileceğini unutmayın. yöntemi bildirilirse MustOverride, bu bazı devralma zincirlerinin mümkün olmayabileceği anlamına gelir. Örneğin:
MustInherit Class Base(Of T, U)
Public MustOverride Sub S1(x As T)
Public MustOverride Sub S1(y As U)
End Class
Class Derived
Inherits Base(Of Integer, Integer)
' Error: Can't override both S1's at once
Public Overrides Sub S1(x As Integer)
End Sub
End Class
Geçersiz kılma bildirimi, aşağıdaki örnekte olduğu gibi temel erişim kullanarak geçersiz kılınan temel yönteme erişebilir:
Class Base
Private x As Integer
Public Overridable Sub PrintVariables()
Console.WriteLine("x = " & x)
End Sub
End Class
Class Derived
Inherits Base
Private y As Integer
Public Overrides Sub PrintVariables()
MyBase.PrintVariables()
Console.WriteLine("y = " & y)
End Sub
End Class
Örnekte, sınıfında çağrısıMyBase.PrintVariables(), sınıfında Derived bildirilen Baseyöntemini çağırırPrintVariables. Temel erişim, geçersiz kılınabilir çağırma mekanizmasını devre dışı bırakır ve temel yöntemi geçersiz kılınamaz bir yöntem olarak ele alır. çağrısı Derived yazılmış CType(Me, Base).PrintVariables()olsaydı, içinde bildirilen yöntemi değil, içinde Derivedbildirilen Baseyöntemi yinelemeli olarak çağırırdıPrintVariables.
Yalnızca bir Overrides değiştirici içerdiğinde bir yöntem başka bir yöntemi geçersiz kılabilir. Diğer tüm durumlarda, devralınan yöntemle aynı imzaya sahip bir yöntem, aşağıdaki örnekte olduğu gibi devralınan yöntemi gölgeler:
Class Base
Public Overridable Sub F()
End Sub
End Class
Class Derived
Inherits Base
Public Overridable Sub F() ' Warning, shadowing inherited F().
End Sub
End Class
Örnekte, sınıfındaki Derived yöntemi F bir Overrides değiştirici içermez ve bu nedenle sınıfında Baseyöntemini F geçersiz kılmaz. Bunun yerine, sınıfındaki Derived yöntemi F sınıfındaki Baseyöntemi gölgeler ve bildirimi bir veya Overloads değiştirici içermediğinden bir Shadows uyarı bildirilir.
Aşağıdaki örnekte, sınıfındaki yöntemiF, sınıfından Derived devralınan Basegeçersiz kılınabilir yöntemi F gölgeler:
Class Base
Public Overridable Sub F()
End Sub
End Class
Class Derived
Inherits Base
Private Shadows Sub F() ' Shadows Base.F within Derived.
End Sub
End Class
Class MoreDerived
Inherits Derived
Public Overrides Sub F() ' Ok, overrides Base.F.
End Sub
End Class
sınıfındaki yeni yöntemin F erişimi olduğundanPrivate, kapsamı yalnızca öğesinin sınıf gövdesini Derived içerir ve sınıfına MoreDerivedgenişletilmez.Derived Bu nedenle sınıfında MoreDerived yöntemi F bildiriminin sınıfından Basedevralınan yöntemi F geçersiz kılmasına izin verilir.
Bir Overridable yöntem çağrıldığında, örnek yönteminin en türetilmiş uygulaması, çağrının temel sınıftaki veya türetilmiş sınıftaki yöntemine olmasına bakılmaksızın, örneğin türüne göre çağrılır. Bir yöntemin M sınıfa OverridableR göre en türetilmiş uygulaması aşağıdaki gibi belirlenir:
Rgiriş bildiriminiMiçeriyorsaOverridable, bu en türetilmiş uygulamasıdırM.Aksi takdirde,
Rgeçersiz kılmaMiçeriyorsa, bu en türetilmiş uygulamasıdırM.Aksi takdirde, en türetilmiş uygulaması
Mdoğrudan temel sınıfıylaRaynıdır.
Erişilebilirlik
Bildirim, bildirmiş olduğu varlığın erişilebilirliğini belirtir. Varlığın erişilebilirliği, varlığın adının kapsamını değiştirmez. Bildirimin erişilebilirlik etki alanı , bildirilen varlığın erişilebilir olduğu tüm bildirim alanları kümesidir.
Beş erişim türü , , ProtectedFriend, Protected Friendve PrivateşeklindedirPublic.
Public en izinli erişim türüdür ve diğer dört tür de alt kümeleridir Public. En az izinli erişim türü olur Privateve diğer dört erişim türünün tümü üst kümeleridir Private.
AccessModifier
: 'Public'
| 'Protected'
| 'Friend'
| 'Private'
| 'Protected' 'Friend'
;
Bildirimin erişim türü, , , ProtectedFriend, Privateveya ve birleşimi olabilecek Publicisteğe bağlı bir erişim değiştirici aracılığıyla ProtectedFriendbelirtilir. Hiçbir erişim değiştirici belirtilmezse, varsayılan erişim türü bildirim bağlamına bağlıdır; izin verilen erişim türleri de bildirim bağlamına bağlıdır.
Değiştirici ile bildirilen varlıkların
Publicerişimi vardırPublic. Varlıkların kullanımıylaPublicilgili bir kısıtlama yoktur.Değiştirici ile bildirilen varlıkların
Protectederişimi vardırProtected.Protectederişim yalnızca sınıfların üyelerinde (hem normal tür üyeleri hem de iç içe sınıflar) veya standart modüllerin ve yapıların üyelerindeOverridablebelirtilebilir (tanım gereği veyaSystem.ValueTypeöğesindenSystem.Objectdevralınması gerekir).ProtectedÜyenin örnek üyesi olmaması veya erişimin türetilmiş sınıfın bir örneği aracılığıyla gerçekleşmesi koşuluyla, üye türetilmiş bir sınıf için erişilebilir.Protectederişim, bir erişim üst kümesiFrienddeğildir.Değiştirici ile bildirilen varlıkların
Frienderişimi vardırFriend. Erişimi olanFriendbir varlığa yalnızca varlık bildirimini veya özniteliği aracılığıylaSystem.Runtime.CompilerServices.InternalsVisibleToAttributeerişim verilmişFriendtüm derlemeleri içeren program içinden erişilebilir.Değiştiricilerle
Protected Friendbildirilen varlıklar veFrienderişim birleşimineProtectedsahiptir.Değiştirici ile bildirilen varlıkların
Privateerişimi vardırPrivate. BirPrivatevarlık, iç içe yerleştirilmiş varlıklar da dahil olmak üzere yalnızca bildirim bağlamında erişilebilir.
Bildirimdeki erişilebilirlik, bildirim bağlamının erişilebilir olmasına bağlı değildir. Örneğin, erişimle Private bildirilen bir tür, erişimi olan Public bir tür üyesi içerebilir.
Aşağıdaki kod çeşitli erişilebilirlik etki alanlarını gösterir:
Public Class A
Public Shared X As Integer
Friend Shared Y As Integer
Private Shared Z As Integer
End Class
Friend Class B
Public Shared X As Integer
Friend Shared Y As Integer
Private Shared Z As Integer
Public Class C
Public Shared X As Integer
Friend Shared Y As Integer
Private Shared Z As Integer
End Class
Private Class D
Public Shared X As Integer
Friend Shared Y As Integer
Private Shared Z As Integer
End Class
End Class
Bu örnekteki sınıflar ve üyeler aşağıdaki erişilebilirlik etki alanlarına sahiptir:
AveA.Xerişilebilirlik etki alanı sınırsızdır., ,
B, ,B.XB.Y,B.C, ,B.C.XveB.C.Yerişilebilirlik etki alanıA.Y, içeren programdır.erişilebilirlik etki alanı
A.Z:A., ,
B.Dve erişilebilirlik etki alanıB.Z, veB.Ddahil olmak üzereB.CşeklindedirB.B.D.YB.D.Xerişilebilirlik etki alanı
B.C.ZşeklindedirB.C.erişilebilirlik etki alanı
B.D.ZşeklindedirB.D.
Örnekte gösterildiği gibi, bir üyenin erişilebilirlik etki alanı hiçbir zaman içeren türden büyük değildir. Örneğin, tüm X üyeler erişilebilirlik bildirmiş Public olsa da, A.X ancak tüm üyelerin içeren bir türle kısıtlanmış erişilebilirlik etki alanları vardır.
Örnek üyelerine Protected erişim, ilişkili olmayan türlerin birbirlerinin korumalı üyelerine erişim sağlayamaması için türetilmiş türün bir örneği aracılığıyla olmalıdır. Örneğin:
Class User
Protected Password As String
End Class
Class Employee
Inherits User
End Class
Class Guest
Inherits User
Public Function GetPassword(u As User) As String
' Error: protected access has to go through derived type.
Return U.Password
End Function
End Class
Yukarıdaki örnekte, sınıfın Guest yalnızca bir örneğiyle Guestnitelenmişse korumalı Password alana erişimi vardır. Bu, yalnızca öğesine dönüştürerek nesnenin Employee alanına erişim Password kazanmasını UserönlerGuest.
Genel türlerde üye erişimi amacıyla Protected bildirim bağlamı tür parametrelerini içerir. Bu, tür bağımsız değişkenlerinden oluşan bir tür kümesine sahip türetilmiş bir türün, türetilmiş bir türün üyelerine Protected farklı tür bağımsız değişkenleriyle erişimi olmadığı anlamına gelir. Örneğin:
Class Base(Of T)
Protected x As T
End Class
Class Derived(Of T)
Inherits Base(Of T)
Public Sub F(y As Derived(Of String))
' Error: Derived(Of T) cannot access Derived(Of String)'s
' protected members
y.x = "a"
End Sub
End Class
Not. C# dili (ve büyük olasılıkla diğer diller), genel bir türün hangi tür bağımsız değişkenlerin sağlandığından bağımsız olarak üyelere erişmesine Protected izin verir. Bu, üye içeren Protected genel sınıflar tasarlarken göz önünde bulundurulmalıdır.
Kurucu Türler
Bildirimin kurucu türleri , bildirim tarafından başvuruda bulunan türlerdir. Örneğin, bir sabitin türü, bir yöntemin dönüş türü ve bir oluşturucunun parametre türleri tüm bağlı türlerdir. Bir bildirimin bağlı türündeki erişilebilirlik etki alanı, bildirimin erişilebilirlik etki alanıyla veya üst kümesiyle aynı olmalıdır. Örneğin:
Public Class X
Private Class Y
End Class
' Error: Exposing private class Y outside of X.
Public Function Z() As Y
End Function
' Valid: Not exposing outside of X.
Private Function A() As Y
End Function
End Class
Friend Class B
Private Class C
End Class
' Error: Exposing private class Y outside of B.
Public Function D() As C
End Function
End Class
Tür ve Ad Alanı Adları
Birçok dil yapısı için ad alanı veya türün belirtilmesi gerekir; bunlar ad alanının veya türün adının nitelikli bir biçimi kullanılarak belirtilebilir. Nitelenmiş ad, noktalarla ayrılmış bir dizi tanımlayıcıdan oluşur; bir dönemin sağ tarafındaki tanımlayıcı, dönemin sol tarafındaki tanımlayıcı tarafından belirtilen bildirim alanında çözümlenir.
Ad alanı veya türün tam adı , ad alanlarını ve türleri içeren tüm adları içeren tam addır. Başka bir deyişle, ad alanı veya türün tam adı , N.Tburada T varlığın adı ve N içeren varlığının tam adıdır.
Aşağıdaki örnekte, satır içi açıklamalarda ilişkili tam adlarıyla birlikte çeşitli ad alanı ve tür bildirimleri gösterilmektedir.
Class A ' A.
End Class
Namespace X ' X.
Class B ' X.B.
Class C ' X.B.C.
End Class
End Class
Namespace Y ' X.Y.
Class D ' X.Y.D.
End Class
End Namespace
End Namespace
Namespace X.Y ' X.Y.
Class E ' X.Y.E.
End Class
End Namespace
X.Y ad alanının kaynak kodunda iki farklı konumda bildirildiğini, ancak bu iki kısmi bildirimin hem D hem de E sınıfını içeren X.Y adlı tek bir ad alanı oluşturduğunu gözlemleyin.
Bazı durumlarda, nitelenmiş bir ad anahtar sözcüğüyle Globalbaşlayabilir. anahtar sözcüğü, bir bildirimin kapsayan ad alanını gölgelediği durumlarda yararlı olan adsız en dıştaki ad alanını temsil eder. anahtar sözcüğü, Global bu durumda en dıştaki ad alanına "kaçış" sağlar. Örneğin:
Namespace NS1
Class System
End Class
Module Test
Sub Main()
' Error: Class System does not contain Int32
Dim x As System.Int32
' Legal, binds to System in outermost namespace
Dim y As Global.System.Int32
End Sub
End Module
End Namespace
Yukarıdaki örnekte, tanımlayıcı System ad alanına Systemdeğil sınıfına Systembağlandığından ilk yöntem çağrısı geçersizdir. Ad alanına erişmenin System tek yolu, en dıştaki ad alanına kaçmak için kullanmaktır Global .
Global bir Imports deyimde veya Namespace bildirimde kullanılamaz.
Diğer diller dildeki anahtar sözcüklerle eşleşen türler ve ad alanları içerebileceğinden, Visual Basic bir dönemi takip ettikleri sürece anahtar sözcükleri nitelenmiş bir adın parçası olarak tanır. Bu şekilde kullanılan anahtar sözcükler tanımlayıcı olarak değerlendirilir. Örneğin, nitelenmiş tanımlayıcı X.Default.Class geçerli bir nitelenmiş tanımlayıcıdır, ancak Default.Class geçerli değildir.
Ad alanları ve türler için Nitelenmiş Ad Çözümlemesi
formun N.R(Of A)nitelenmiş ad alanı veya tür adı verildiğinde, burada R nitelenmiş ad alanında en sağdaki tanımlayıcıdır ve A isteğe bağlı bir tür bağımsız değişken listesidir, aşağıdaki adımlarda nitelenmiş adın başvurduğu ad alanının veya türün nasıl belirleneceği açıklanmaktadır:
nitelenmiş veya nitelenmemiş ad çözümlemesi için kuralları kullanarak sorununu çözün
N.Çözümleme
Nbaşarısız olursa veya bir tür parametresine çözümlendiğinde derleme zamanı hatası oluşur.Aksi takdirde, N'deki bir ad alanının adıyla eşleşiyorsa ve hiçbir tür bağımsız değişkeni sağlanmadıysa
RveyaRtür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir bir türleNeşleşiyorsa, varsa, nitelenmiş ad alanı veya türe başvurur.Aksi takdirde,
Nbir veya daha fazla standart modül içeriyorsa veRtam olarak bir standart modülde tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir bir türün adıyla eşleşiyorsa, tam ad bu türe başvurur. BirdenRfazla standart modülde, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir türlerin adıyla eşleşiyorsa, derleme zamanı hatası oluşur.Aksi takdirde derleme zamanı hatası oluşur.
Not. Bu çözümleme işleminin bir etkisi, ad alanı veya tür adlarını çözümlerken tür üyelerinin ad alanlarını veya türleri gölgelememesidir.
Ad alanları ve türler için nitelenmemiş Ad Çözümlemesi
İsteğe bağlı tür bağımsız değişken listesi olan A nitelenmemiş bir ad R(Of A)verildiğinde, aşağıdaki adımlarda nitelenmemiş adın hangi ad alanına başvurduğu veya yazacağı açıklanmaktadır:
R geçerli yöntemin tür parametresinin adıyla eşleşiyorsa ve hiçbir tür bağımsız değişkeni sağlanmamışsa, nitelenmemiş ad bu tür parametresine başvurur.
En içteki türden başlayıp en dıştakine giderek ad başvuruyu içeren her iç içe tür için:
- Geçerli türdeki tür parametresinin adıyla eşleşiyorsa ve hiçbir tür bağımsız değişkeni sağlanmamışsa
R, nitelenmemiş ad bu tür parametresine başvurur. - Aksi takdirde
R, varsa, tür bağımsız değişkenleriyle aynı sayıda tür parametresiyle erişilebilir bir iç içe türün adıyla eşleşiyorsa, nitelenmemiş ad bu türe başvurur.
- Geçerli türdeki tür parametresinin adıyla eşleşiyorsa ve hiçbir tür bağımsız değişkeni sağlanmamışsa
En içteki ad alanından başlayıp en dıştaki ad alanına giderek ad başvurularını içeren her iç içe yerleştirilmiş ad alanı için:
- Geçerli ad alanında iç içe bir ad alanının adıyla eşleşiyorsa
Rve hiçbir tür bağımsız değişken listesi sağlanmazsa, nitelenmemiş ad alanı bu iç içe ad alanına başvurur. - Aksi takdirde
R, geçerli ad alanında varsa, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir bir türün adıyla eşleşiyorsa, nitelenmemiş ad bu türe başvurur. - Aksi takdirde, ad alanı bir veya daha fazla erişilebilir standart modül içeriyorsa ve
Rvarsa, tam olarak bir standart modülde tür bağımsız değişkenleriyle aynı sayıda tür parametresiyle erişilebilir bir iç içe türün adıyla eşleşiyorsa, nitelenmemiş ad bu iç içe türü ifade eder. BirdenRfazla standart modülde, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir iç içe türlerin adıyla eşleşiyorsa, derleme zamanı hatası oluşur.
- Geçerli ad alanında iç içe bir ad alanının adıyla eşleşiyorsa
Kaynak dosyada bir veya daha fazla içeri aktarma diğer adı varsa ve
Rbunlardan birinin adıyla eşleşiyorsa, nitelenmemiş ad bu içeri aktarma diğer adına başvurur. Tür bağımsız değişkeni listesi sağlanırsa, derleme zamanı hatası oluşur.Ad başvuruyu içeren kaynak dosyada bir veya daha fazla içeri aktarma varsa:
- Tam
Rolarak bir içeri aktarmada, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir bir türün adıyla eşleşiyorsa, nitelenmemiş ad bu türe başvurur. ErişilebilirRbir türün adı, tür bağımsız değişkenleriyle aynı sayıda tür parametresiyle eşleşiyorsa , varsa, birden fazla içeri aktarmada ve tümü aynı türde değilse, derleme zamanı hatası oluşur. - Aksi takdirde, hiçbir tür bağımsız değişken listesi sağlanmamışsa ve
Rtam olarak bir içeri aktarmada erişilebilir türleri olan bir ad alanının adıyla eşleşiyorsa, nitelenmemiş ad alanı bu ad alanına başvurur. Hiçbir tür bağımsız değişken listesi sağlanmadıysa veRbirden fazla içeri aktarmada erişilebilir türler içeren bir ad alanının adıyla eşleşiyorsa ve hepsi aynı ad alanı değilse, derleme zamanı hatası oluşur. - Aksi takdirde, içeri aktarmalar bir veya daha fazla erişilebilir standart modül içeriyorsa ve
Rvarsa, tam olarak bir standart modülde tür bağımsız değişkenleriyle aynı sayıda tür parametresiyle erişilebilir bir iç içe türün adıyla eşleşiyorsa, nitelenmemiş ad bu türe başvurur. BirdenRfazla standart modülde, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir iç içe türlerin adıyla eşleşiyorsa, derleme zamanı hatası oluşur.
- Tam
Derleme ortamı bir veya daha fazla içeri aktarma diğer adını tanımlıyorsa ve
Rbunlardan birinin adıyla eşleşiyorsa, nitelenmemiş ad bu içeri aktarma diğer adına başvurur. Tür bağımsız değişkeni listesi sağlanırsa, derleme zamanı hatası oluşur.Derleme ortamı bir veya daha fazla içeri aktarma tanımlıyorsa:
- Tam
Rolarak bir içeri aktarmada, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir bir türün adıyla eşleşiyorsa, nitelenmemiş ad bu türe başvurur. BirdenRfazla içeri aktarmada, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir bir türün adıyla eşleşiyorsa, derleme zamanı hatası oluşur. - Aksi takdirde, hiçbir tür bağımsız değişken listesi sağlanmamışsa ve
Rtam olarak bir içeri aktarmada erişilebilir türleri olan bir ad alanının adıyla eşleşiyorsa, nitelenmemiş ad alanı bu ad alanına başvurur. Hiçbir tür bağımsız değişken listesi sağlanmadıysa veRbirden fazla içeri aktarmada erişilebilir türleri olan bir ad alanının adıyla eşleşiyorsa, derleme zamanı hatası oluşur. - Aksi takdirde, içeri aktarmalar bir veya daha fazla erişilebilir standart modül içeriyorsa ve
Rvarsa, tam olarak bir standart modülde tür bağımsız değişkenleriyle aynı sayıda tür parametresiyle erişilebilir bir iç içe türün adıyla eşleşiyorsa, nitelenmemiş ad bu türe başvurur. BirdenRfazla standart modülde, tür bağımsız değişkenleriyle aynı sayıda tür parametresine sahip erişilebilir iç içe türlerin adıyla eşleşiyorsa, derleme zamanı hatası oluşur.
- Tam
Aksi takdirde derleme zamanı hatası oluşur.
Not. Bu çözümleme işleminin bir etkisi, ad alanı veya tür adlarını çözümlerken tür üyelerinin ad alanlarını veya türleri gölgelememesidir.
Normalde, bir ad belirli bir ad alanında yalnızca bir kez oluşabilir. Ancak, ad alanları birden çok .NET derlemesi arasında bildirilebildiği için, iki derlemenin aynı tam ada sahip bir tür tanımladığı bir duruma sahip olmak mümkündür. Bu durumda, geçerli kaynak dosya kümesinde bildirilen bir tür, dış .NET derlemesinde bildirilen bir türe göre tercih edilir. Aksi takdirde, ad belirsizdir ve adı kesinleştirmenin bir yolu yoktur.
Değişkenler
Değişken bir depolama konumunu temsil eder. Her değişkenin, değişkende hangi değerlerin depolanabileceğini belirleyen bir türü vardır. Visual Basic tür açısından güvenli bir dil olduğundan, programdaki her değişkenin bir türü vardır ve dil, değişkenlerde depolanan değerlerin her zaman uygun türde olduğunu garanti eder. Değişkenlere herhangi bir başvuru yapılamadan önce değişkenler her zaman türünün varsayılan değerine başlatılır. Başlatılmamış belleğe erişmek mümkün değildir.
Genel Türler ve Yöntemler
Türler (standart modüller ve numaralandırılmış türler dışında) ve yöntemler, türün bir örneği bildirilene veya yöntemi çağrılana kadar sağlanmayan tür parametreleri bildirebilir. Tür veya yöntemin, türü veya yöntemi kullanan kod tarafından sağlanacak türler hakkında belirli bir bilgi olmadan genel olarak yazılması gerektiğinden, tür parametrelerine sahip türler ve yöntemler sırasıyla genel türler ve genel yöntemler olarak da bilinir.
Not. Şu anda yöntemler ve temsilciler genel olsa da özellikler, olaylar ve işleçler genel olamaz. Ancak, içeren sınıftan tür parametrelerini kullanabilirler.
Genel tür veya yöntem açısından bakıldığında tür parametresi, tür veya yöntem kullanıldığında gerçek bir türle doldurulacak yer tutucu bir türdür. Tür bağımsız değişkenleri, türün veya yöntemin kullanıldığı noktada tür veya yöntemdeki tür parametreleriyle değiştirilir. Örneğin, genel bir yığın sınıfı şu şekilde uygulanabilir:
Public Class Stack(Of ItemType)
Protected Items(0 To 99) As ItemType
Protected CurrentIndex As Integer = 0
Public Sub Push(data As ItemType)
If CurrentIndex = 100 Then
Throw New ArgumentException("Stack is full.")
End If
Items(CurrentIndex) = Data
CurrentIndex += 1
End Sub
Public Function Pop() As ItemType
If CurrentIndex = 0 Then
Throw New ArgumentException("Stack is empty.")
End If
CurrentIndex -= 1
Return Items(CurrentIndex + 1)
End Function
End Class
sınıfını Stack(Of ItemType) kullanan bildirimler, tür parametresi ItemTypeiçin bir tür bağımsız değişkeni sağlamalıdır. Bu tür daha sonra sınıfın içinde kullanılan her yerde ItemType doldurulur:
Option Strict On
Module Test
Sub Main()
Dim s1 As New Stack(Of Integer)()
Dim s2 As New Stack(Of Double)()
s1.Push(10.10) ' Error: Stack(Of Integer).Push takes an Integer
s2.Push(10.10) ' OK: Stack(Of Double).Push takes a Double
Console.WriteLine(s2.Pop().GetType().ToString()) ' Prints: Double
End Sub
End Module
Tür Parametreleri
Tür parametreleri tür veya yöntem bildirimlerinde sağlanabilir. Her tür parametresi, bir tür bağımsız değişkeninin yer tutucusu olan ve yapılı bir tür veya yöntem oluşturmak için sağlanan bir tanımlayıcıdır. Buna karşılık, tür bağımsız değişkeni, genel bir tür veya yöntem kullanıldığında tür parametresinin yerini alan gerçek türdür.
TypeParameterList
: OpenParenthesis 'Of' TypeParameter ( Comma TypeParameter )* CloseParenthesis
;
TypeParameter
: VarianceModifier? Identifier TypeParameterConstraints?
;
VarianceModifier
: 'In' | 'Out'
;
Tür veya yöntem bildirimindeki her tür parametresi, bu tür veya yöntemin bildirim alanında bir ad tanımlar. Bu nedenle, başka bir tür parametresi, tür üyesi, yöntem parametresi veya yerel değişken ile aynı ada sahip olamaz. Tür veya yöntemdeki tür parametresinin kapsamı, türün veya yöntemin tamamıdır. Tür parametrelerinin kapsamı tür bildiriminin tamamına göre belirlenmiş olduğundan, iç içe türler dış tür parametrelerini kullanabilir. Bu, genel türlerin içinde iç içe yerleştirilmiş türlere erişirken tür parametrelerinin her zaman belirtilmesi gerektiği anlamına da gelir:
Public Class Outer(Of T)
Public Class Inner
Public Sub F(x As T)
...
End Sub
End Class
End Class
Module Test
Sub Main()
Dim x As New Outer(Of Integer).Inner()
...
End Sub
End Module
Sınıfın diğer üyelerinden farklı olarak tür parametreleri devralınmıyor. Türdeki tür parametrelerine yalnızca basit adlarıyla başvurulabilir; başka bir deyişle, içeren tür adıyla nitelenemezler. Hatalı programlama stili olsa da, iç içe bir türdeki tür parametreleri dış türde bildirilen bir üyeyi veya tür parametresini gizleyebilir:
Class Outer(Of T)
Class Inner(Of T)
Public t1 As T ' Refers to Inner's T
End Class
End Class
Türler ve yöntemler, türlerin veya yöntemlerin bildirmiş olduğu tür parametrelerinin (veya arity) sayısına göre aşırı yüklenebilir. Örneğin, aşağıdaki bildirimler yasaldır:
Module C
Sub M()
End Sub
Sub M(Of T)()
End Sub
Sub M(Of T, U)()
End Sub
End Module
Structure C(Of T)
Dim x As T
End Structure
Class C(Of T, U)
End Class
Türler söz konusu olduğunda, aşırı yüklemeler her zaman belirtilen tür bağımsız değişken sayısıyla eşleştirilir. Bu, aynı programda hem genel hem de genel olmayan sınıfları birlikte kullanırken kullanışlıdır:
Class Queue
End Class
Class Queue(Of T)
End Class
Class X
Dim q1 As Queue ' Non-generic queue
Dim q2 As Queue(Of Integer) ' Generic queue
End Class
Tür parametrelerinde aşırı yüklenen yöntemlerin kuralları, yöntem aşırı yükleme çözümlemesi bölümünde ele alınmıştır.
içeren bildiriminde tür parametreleri tam türler olarak kabul edilir. Bir tür parametresinin örneği birçok farklı gerçek tür bağımsız değişkeniyle oluşturulabildiğinden, tür parametreleri aşağıda açıklandığı gibi diğer türlerden biraz farklı işlemlere ve kısıtlamalara sahiptir:
Tür parametresi doğrudan bir temel sınıf veya arabirim bildirmek için kullanılamaz.
Tür parametrelerinde üye arama kuralları, tür parametresine uygulanan kısıtlamalara (varsa) bağlıdır.
Tür parametresi için kullanılabilir dönüştürmeler, varsa tür parametrelerine uygulanan kısıtlamalara bağlıdır.
Kısıtlama olmadığında
Structure, bir tür parametresiyle temsil edilen türe sahip bir değer veIsNotileIskarşılaştırılabilirNothing.Tür parametresi yalnızca tür parametresi bir
NewveyaStructurekısıtlaması tarafındanNewkısıtlanmışsa ifadede kullanılabilir.Tür parametresi, bir ifade içindeki öznitelik özel durumu içinde herhangi bir
GetTypeyerde kullanılamaz.Tür parametreleri, diğer genel türler ve parametreler için tür bağımsız değişkenleri olarak kullanılabilir.
Aşağıdaki örnek, sınıfını genişleten Stack(Of ItemType) genel bir türdür:
Class MyStack(Of ItemType)
Inherits Stack(Of ItemType)
Public ReadOnly Property Size() As Integer
Get
Return CurrentIndex
End Get
End Property
End Class
Bir bildirim için MyStackbir tür bağımsız değişkeni sağladığında, aynı tür bağımsız değişkeni de uygulanır Stack .
Tür olarak, tür parametreleri yalnızca bir derleme zamanı yapısıdır. Çalışma zamanında, her tür parametresi, genel bildirime bir tür bağımsız değişkeni sağlayarak belirtilen bir çalışma zamanı türüne bağlıdır. Bu nedenle, tür parametresiyle bildirilen bir değişkenin türü, çalışma zamanında genel olmayan bir tür veya belirli bir yapılı tür olacaktır. Tür parametreleriyle ilgili tüm deyimlerin ve ifadelerin çalışma zamanı yürütmesi, bu parametre için tür bağımsız değişkeni olarak sağlanan gerçek türü kullanır.
Tür Kısıtlamaları
Tür bağımsız değişkeni tür sistemindeki herhangi bir tür olabileceğinden, genel bir tür veya yöntem tür parametresi hakkında herhangi bir varsayımda bulunamaz. Bu nedenle, bir tür parametresinin üyeleri türünün üyeleri Objectolarak kabul edilir, çünkü tüm türler türünden Objecttüretilir.
gibi Stack(Of ItemType)bir koleksiyon söz konusu olduğunda, bu olgu özellikle önemli bir kısıtlama olmayabilir, ancak genel bir türün tür bağımsız değişkenleri olarak sağlanacak türler hakkında bir varsayımda bulunmak isteyebileceği durumlar olabilir.
Tür kısıtlamaları , tür parametresi olarak hangi türlerin sağlanabileceğini kısıtlayan ve genel türlerin veya yöntemlerin tür parametreleri hakkında daha fazla bilgi edinebilmesini sağlayan tür parametrelerine yerleştirilebilir.
TypeParameterConstraints
: 'As' Constraint
| 'As' OpenCurlyBrace ConstraintList CloseCurlyBrace
;
ConstraintList
: Constraint ( Comma Constraint )*
;
Constraint
: TypeName
| 'New'
| 'Structure'
| 'Class'
;
Public Class DisposableStack(Of ItemType As IDisposable)
Implements IDisposable
Private _items(0 To 99) As ItemType
Private _currentIndex As Integer = 0
Public Sub Push(data As ItemType)
...
End Sub
Public Function Pop() As ItemType
...
End Function
Private Sub Dispose() Implements IDisposable.Dispose
For Each item As IDisposable In _items
If item IsNot Nothing Then
item.Dispose()
End If
Next item
End Sub
End Class
Bu örnekte, DisposableStack(Of ItemType) türü parametresini yalnızca arabirimini System.IDisposableuygulayan türlerle kısıtlar. Sonuç olarak, kuyrukta kalan nesneleri atan bir Dispose yöntem uygulayabilir.
Tür kısıtlaması, Structure, veya özel kısıtlamalarından Classbiri olmalı veya Newaşağıdaki durumlarda bir tür T olmalıdır:
Tbir sınıf, arabirim veya tür parametresidir.TdeğilNotInheritable.Tşu özel türlerden biri veya türünden devralınmış bir tür değildir:System.Array,System.Delegate,System.MulticastDelegate,System.EnumveyaSystem.ValueType.TdeğilObject. Tüm türler türünden türetildiğindenObject, izin verildiğinde böyle bir kısıtlamanın hiçbir etkisi olmaz.Ten az bildirilen genel tür veya yöntem kadar erişilebilir olmalıdır.
Tür kısıtlamaları küme ayracı ({} ) içine alınarak tek bir tür parametresi için birden çok tür kısıtlaması belirtilebilir. Belirli bir tür parametresi için yalnızca bir tür kısıtlaması sınıf olabilir. Özel bir Structure kısıtlamayı adlandırılmış bir sınıf kısıtlamasıyla veya Class özel kısıtlamayla birleştirmek bir hatadır.
Class ControlFactory(Of T As {Control, New})
...
End Class
Tür kısıtlamaları, içeren türleri veya içeren türlerin tür parametrelerinden herhangi birini kullanabilir. Aşağıdaki örnekte kısıtlama, sağlanan tür bağımsız değişkeninin kendisini tür bağımsız değişkeni olarak kullanan genel bir arabirim uygulamasını gerektirir:
Class Sorter(Of V As IComparable(Of V))
...
End Class
Özel tür kısıtlaması Class , sağlanan tür bağımsız değişkenini herhangi bir başvuru türüyle kısıtlar.
Not. Özel tür kısıtlaması Class bir arabirim tarafından karşılanabilir. Ve bir yapı bir arabirim uygulayabilir. Bu nedenle, kısıtlama (Of T As U, U As Class) "T" bir yapıdan (özel kısıtlamayı Class karşılamayan) ve uyguladığı bir arabirimden (özel kısıtlamayı Class karşılayan) "U" ile karşılanabilir.
Özel tür kısıtlaması Structure , sağlanan tür bağımsız değişkenini dışındaki System.Nullable(Of T)herhangi bir değer türüyle kısıtlar.
Not. Yapı kısıtlamaları, kendisine tür bağımsız değişkeni olarak sağlamanın System.Nullable(Of T) mümkün olmaması için izin System.Nullable(Of T) vermez.
Özel tür kısıtlaması New , sağlanan tür bağımsız değişkeninin erişilebilir bir parametresiz oluşturucuya sahip olmasını gerektirir ve bildirilemez MustInherit. Örneğin:
Class Factory(Of T As New)
Function CreateInstance() As T
Return New T()
End Function
End Class
Sınıf türü kısıtlaması, sağlanan tür bağımsız değişkeninin bu tür olması veya ondan devralması gerekir. Arabirim türü kısıtlaması, sağlanan tür bağımsız değişkeninin bu arabirimi uygulaması gerekir. Tür parametresi kısıtlaması, sağlanan tür bağımsız değişkeninin eşleşen tür parametresi için verilen tüm sınırları türetmesi veya uygulaması gerekir. Örneğin:
Class List(Of T)
Sub AddRange(Of S As T)(collection As IEnumerable(Of S))
...
End Sub
End Class
Bu örnekte, üzerindeki AddRange tür parametresiS, türü parametresiyle TListkısıtlanır. Bu, bir List(Of Control) öğesinin tür parametresini olan veya öğesinden Controldevralan herhangi bir türle sınırlandıracağı AddRangeanlamına gelir.
Tür parametresi kısıtlamasıOf S As T, özel kısıtlamalar (Class, Structure, New) dışında tüm Tkısıtlamaları geçişli olarak öğesine Seklenerek çözülür. Döngüsel kısıtlamaların olması bir hatadır (örn. Of S As T, T As S). Kısıtlamaya sahip tür parametresi kısıtlaması Structure olması bir hatadır. Kısıtlamalar eklendikten sonra, bir dizi özel durum oluşabilir:
Birden çok sınıf kısıtlaması varsa, en çok türetilmiş sınıf kısıtlama olarak kabul edilir. Bir veya daha fazla sınıf kısıtlamasının devralma ilişkisi yoksa, kısıtlama karşılanamaz ve bir hatadır.
Tür parametresi özel bir
Structurekısıtlamayı adlandırılmış sınıf kısıtlamasıyla veya özel kısıtlamaylaClassbirleştirirse, bu bir hatadır. Sınıf kısıtlaması olabilirNotInheritable, bu durumda bu kısıtlamanın türetilmiş türleri kabul edilmez ve bu bir hatadır.
Tür, şu özel türlerden biri veya öğesinden devralınan bir tür olabilir: System.Array, System.Delegate, System.MulticastDelegate, System.Enumveya System.ValueType. Bu durumda, yalnızca türü veya ondan devralınan bir tür kabul edilir. Bu türlerden biriyle kısıtlanmış bir tür parametresi yalnızca işleç tarafından DirectCast izin verilen dönüştürmeleri kullanabilir. Örneğin:
MustInherit Class Base(Of T)
MustOverride Sub S1(Of U As T)(x As U)
End Class
Class Derived
Inherits Base(Of Integer)
' The constraint of U must be Integer, which is normally not allowed.
Overrides Sub S1(Of U As Integer)(x As U)
Dim y As Integer = x ' OK
Dim z As Long = x ' Error: Can't convert
End Sub
End Class
Ayrıca, yukarıdaki gevşemelerden biri nedeniyle bir değer türüyle kısıtlanmış tür parametresi, bu değer türünde tanımlanan hiçbir yöntemi çağıramaz. Örneğin:
Class C1(Of T)
Overridable Sub F(Of G As T)(x As G)
End Sub
End Class
Class C2
Inherits C1(Of IntPtr)
Overrides Sub F(Of G As IntPtr)(ByVal x As G)
' Error: Cannot access structure members
x.ToInt32()
End Sub
End Class
Değiştirmeden sonra kısıtlama bir dizi türü olarak biterse, herhangi bir kovaryan dizi türüne de izin verilir. Örneğin:
Module Test
Class B
End Class
Class D
Inherits B
End Class
Function F(Of T, U As T)(x As U) As T
Return x
End Function
Sub Main()
Dim a(9) As B
Dim b(9) As D
a = F(Of B(), D())(b)
End Sub
End Module
Sınıf veya arabirim kısıtlamasına sahip bir tür parametresinin, bu sınıf veya arabirim kısıtlamasıyla aynı üyelere sahip olduğu kabul edilir. Tür parametresinin birden çok kısıtlaması varsa, tür parametresinin kısıtlamaların tüm üyelerinin birleşimine sahip olduğu kabul edilir. Birden fazla kısıtlamada aynı ada sahip üyeler varsa, üyeler şu sırayla gizlenir: sınıf kısıtlaması, içindeki üyeleri gizleyen (kısıtlama belirtilmişseStructure) arabirim kısıtlamalarındaki System.ValueTypeObjectüyeleri gizler ve içindeki üyeleri gizler. Aynı ada sahip bir üye birden fazla arabirim kısıtlamasında görünüyorsa üye kullanılamaz (birden çok arabirim devralmada olduğu gibi) ve tür parametresi istenen arabirime atanmalıdır. Örneğin:
Class C1
Sub S1(x As Integer)
End Sub
End Class
Interface I1
Sub S1(x As Integer)
End Interface
Interface I2
Sub S1(y As Double)
End Interface
Module Test
Sub T1(Of T As {C1, I1, I2})()
Dim a As T
a.S1(10) ' Calls C1.S1, which is preferred
a.S1(10.10) ' Also calls C1.S1, class is still preferred
End Sub
Sub T2(Of T As {I1, I2})()
Dim a As T
a.S1(10) ' Error: Call is ambiguous between I1.S1, I2.S1
End Sub
End Module
Tür parametrelerini tür bağımsız değişkenleri olarak sağlarken, tür parametrelerinin eşleşen tür parametrelerinin kısıtlamalarını karşılaması gerekir.
Class Base(Of T As Class)
End Class
Class Derived(Of V)
' Error: V does not satisfy the constraints of T
Inherits Base(Of V)
End Class
Kısıtlamada belirtilen örnek yöntemleri de dahil olmak üzere örnek üyelerine erişmek için kısıtlanmış tür parametresinin değerleri kullanılabilir.
Interface IPrintable
Sub Print()
End Interface
Class Printer(Of V As IPrintable)
Sub PrintOne(v1 As V)
V1.Print()
End Sub
End Class
Tür Parametresi Varyansı
Arabirimdeki veya temsilci türü bildirimindeki tür parametresi isteğe bağlı olarak bir varyans değiştirici belirtebilir. Varyans değiştiricileri olan tür parametreleri, tür parametresinin arabirimde veya temsilci türünde nasıl kullanılabileceğini kısıtlar, ancak genel bir arabirimin veya temsilci türünün değişken uyumlu tür bağımsız değişkenleriyle başka bir genel türe dönüştürülmesini sağlar. Örneğin:
Class Base
End Class
Class Derived
Inherits Base
End Class
Module Test
Sub Main()
Dim x As IEnumerable(Of Derived) = ...
' OK, as IEnumerable(Of Base) is variant compatible
' with IEnumerable(Of Derived)
Dim y As IEnumerable(Of Base) = x
End Sub
End Module
Varyans değiştiricileri olan tür parametrelerine sahip genel arabirimlerin çeşitli kısıtlamaları vardır:
Parametre listesini belirten bir olay bildirimi içeremezler (ancak özel olay bildirimine veya temsilci türüne sahip bir olay bildirimine izin verilir).
İç içe geçmiş bir sınıf, yapı veya numaralandırılmış tür içeremezler.
Not. Bu kısıtlamalar, genel türlerde iç içe yerleştirilmiş türlerin üstlerinin genel parametrelerini örtük olarak kopyalamalarından kaynaklanır. İç içe geçmiş sınıflar, yapılar veya numaralandırılmış türler söz konusu olduğunda, bu tür türlerin tür parametrelerinde varyans değiştiricileri olamaz. Parametre listesi içeren bir olay bildirimi söz konusu olduğunda, oluşturulan iç içe temsilci sınıfı, bir konumda (parametre türü gibi) gerçekten bir konumda (örneğin olayın türü) kullanılıyor gibi görünen bir InOut tür kullanıldığında kafa karıştırıcı hatalar olabilir.
Out değiştiricisi ile bildirilen tür parametresi birlikte değişkendir. Gayri resmi olarak, bir kovarant türü parametresi yalnızca bir çıkış konumunda (arabirimden veya temsilci türünden döndürülen bir değer) kullanılabilir ve giriş konumunda kullanılamaz. Aşağıdakiler durumunda bir türün Taynı anda geçerli olduğu kabul edilir:
Tbir sınıf, yapı veya numaralandırılmış türdür.Tgenel olmayan temsilci veya arabirim türüdür.T, öğe türü aynı anda geçerli olan bir dizi türüdür.Ttür parametresi olarak bildirilmemiş birOuttür parametresidir.T, aşağıdaki gibi tür bağımsız değişkenleriyleA1,...,Anoluşturulan bir arabirim veya temsilci türüdürX(Of P1,...,Pn):Out türü parametresi
Aiolarak bildirildiysePi, aynı anda geçerli olur.In türü parametresi
Aiolarak bildirildiysePi, ters değişken olarak geçerli olur.
Aşağıdakiler bir arabirimde veya temsilci türünde birlikte geçerli olmalıdır:
Bir arabirimin temel arabirimi.
bir işlevin veya temsilci türünün dönüş türü.
Erişimci varsa özelliğin
Gettürü.Herhangi bir
ByRefparametrenin türü.
Örneğin:
Delegate Function D(Of Out T, U)(x As U) As T
Interface I1(Of Out T)
End Interface
Interface I2(Of Out T)
Inherits I1(Of T)
' OK, T is only used in an Out position
Function M1(x As I1(Of T)) As T
' Error: T is used in an In position
Function M2(x As T) As T
End Interface
Not.
Out ayrılmış bir sözcük değildir.
In değiştiricisi ile bildirilen tür parametresi değişkensizdir. Kayıt dışı olarak, değişken karşıtı bir tür parametresi yalnızca giriş konumunda (arabirime veya temsilci türüne geçirilen bir değer) kullanılabilir ve çıkış konumunda kullanılamaz. Bir türün T aşağıdakiler için geçerli olduğu kabul edilir:
Tbir sınıf, yapı veya numaralandırılmış türdür.Tgenel olmayan bir temsilci veya arabirim türüdür.T, öğe türü ters değişken olarak geçerli olan bir dizi türüdür.T, In türü parametresi olarak bildirilmemiş bir tür parametresidir.T, aşağıdaki gibi tür bağımsız değişkenleriyleA1,...,Anoluşturulan bir arabirim veya temsilci türüdürX(Of P1,...,Pn):Tür parametresi
AiolarakOutbildirildiysePi, ters değişken olarak geçerli olur.Tür parametresi
AiolarakInbildirildiysePi, aynı anda geçerli olur.
Aşağıdakiler bir arabirimde veya temsilci türünde ters değişken olarak geçerli olmalıdır:
Parametrenin türü.
Yöntem türü parametresinde tür kısıtlaması.
Bir erişimci varsa
Setözelliğin türü.Bir olayın türü.
Örneğin:
Delegate Function D(Of T, In U)(x As U) As T
Interface I1(Of In T)
End Interface
Interface I2(Of In T)
' OK, T is only used in an In position
Sub M1(x As I1(Of T))
' Error: T is used in an Out position
Function M2() As T
End Interface
Bir türün geçerli olması gereken durumlarda değişken türü parametresi kullanılamaz (hem hem de GetSet erişimcisi veya parametresi olan bir ByRef özellik gibi) değişken türü parametresi kullanılamaz.
Ko-ve kontra-varyans bir "elmas belirsizlik problemine" neden olur. Aşağıdaki kodu inceleyin:
Class C
Implements IEnumerable(Of String)
Implements IEnumerable(Of Exception)
Public Function GetEnumerator1() As IEnumerator(Of String) _
Implements IEnumerable(Of String).GetEnumerator
Console.WriteLine("string")
End Function
Public Function GetEnumerator2() As IEnumerator(Of Exception) _
Implements IEnumerable(Of Execption).GetEnumerator
Console.WriteLine("exception")
End Function
End Class
Dim c As IEnumerable(Of Object) = New C
c.GetEnumerator()
sınıfıC, hem öğesinden hem de öğesinden IEnumerable(Of String) birlikte değişken dönüştürme yoluyla IEnumerable(Of Exception)iki şekilde dönüştürülebilirIEnumerable(Of Object). CLR, iki yöntemden hangisinin tarafından c.GetEnumerator()çağrılacağını belirtmez. Genel olarak, bir sınıf ortak bir üst türe (örneğin, bu örnekte String ve Exception ortak üst Objecttüre sahip) sahip iki farklı genel bağımsız değişken ile birlikte değişken bir arabirim uygulamak üzere bildirildiğinde veya ortak bir alt türü olan iki farklı genel bağımsız değişkene sahip bir ters değişken arabirimi uygulamak için bir sınıf bildirildiğinde, belirsizlik ortaya çıkabilir. Derleyici, bu tür bildirimler hakkında bir uyarı verir.
Visual Basic language spec