2010-05-07 14 views
6

bir Sipariş sistemini temsil eden aşağıdaki sınıfları dikkate alın:Bir özelliği geçersiz kılmak ve VB.NET'te türetilmiş bir tür döndürmek mümkün mü?

Public Class WebOrder 
    Inherits OrderBase   

    Public Overrides Property OrderItem as WebOrderItem 
    End Property 
End Class 

Public Class WebOrderItem 
    Inherits OrderItemBase 
End Class 

: Artık

Public Class OrderBase 
    Public MustOverride Property OrderItem as OrderItemBase 
End Class 

Public Class OrderItemBase 
End Class 

, biz OrderBase toplam doğasını tutarak, sipariş sınıfların daha spesifik bir dizi bu sınıflar uzatmak istediğinizi varsayalım WebOrder sınıfındaki Overriden özelliği, dönüş türünün OrderBase'de tanımlanandan farklı olduğunu bildiren bir hataya neden olur ... ancak dönüş türü, OrderBase'de tanımlanan türün bir alt sınıfıdır. VB buna neden izin vermiyor?

+0

Sipariş öğelerinizi bir dizi olarak tanımlamak zaten kötü bir fikirdir. Bir liste veya bir numara kullanın. –

+0

Gerçek kodumda listeler.() Ile karışıklık için özür dilerim. –

+1

Ayrıca, [bu C# sorusu] 'nun (http://stackoverflow.com/questions/157119/c-sharp-can-i-override-with-derived-types) nedenleri ve püf noktaları/çözümleri için yanıtlarına da bakın. ([C# 'nin metodu imzası "yeni", VB.Net'te "Gölgeler" dir] (http://stackoverflow.com/questions/8575418/difference-between-shadows-vb-net-and-new-c)) –

cevap

7

Bunu yapamazsınız - tabanda tanımlı imzayı değiştiriyor. Eğer generics de kullanmak gerekiyor çalıştığımız şeyi yapmak için:

Public Class OrderBase(Of T As IOrderItem) 
    Public ReadOnly Property OrderItems As IList(Of T) 
End Class 

Benim Visual Basic yüzden umarım bu doğrudur paslı olduğunu ...

+0

Sözdiziminiz Tamam, ama genel bir şey cevapsız bir şey kaçırdı: Artık özelliği geçersiz kılmaya gerek yok - temel uygulama zaten doğru olacaktır. Ayrıca, şimdi orderItems için bir temel sınıftan ziyade bir arayüz kullanabileceğiz. Onu senin için temizledim. –

+0

Ayrıca - Bir dizi yerine bir List kullanma hakkındaki yorumumu ekledim. Hoşlanmıyorsun, sadece geri dönüyor. –

+0

Özelliği, değiştirilemeyecek şekilde değiştirildi; bunun için biçimlendirdiğiniz için teşekkürler. –

4

Bunu geçersiz kılma üzerine sınıfın imza değiştiremezsiniz. Eğer, daha sıkı türlerini uygulamak istediğiniz genel tür kısıtlamaları ile jenerikleri kullanırsanız, aşağıda gösterildiği gibi, Alternatif

Public Overrides Property OrderItem() as OrderItemBase 
    Get 
     Return New WebOrderItem() 
    End Get 
End Property 

Public Sub Whatever() 
    Dim item As WebOrderItem = DirectCast(OrderItem, WebOrderItem) 
End Sub 

:

Public MustInherit Class OrderBase(Of T As OrderItemBase) 
    Public MustOverride ReadOnly Property OrderItem() As T 
End Class 

Public Class OrderItemBase 
End Class 

Public Class WebOrder(Of T As WebOrderItem) 
    Inherits OrderBase(Of T) 

    Public Overrides ReadOnly Property OrderItem() As T 
     Get 
      Return New WebOrderItem() 
     End Get 
    End Property 
End Class 

Public Class WebOrderItem 
    Inherits OrderItemBase 
End Class 

Veya bunu yapmak Ancak, türetilmiş bir tür dönebilirsiniz

Public Class WebOrder 
    Inherits OrderBase(Of WebOrderItem) 

    Public Overrides ReadOnly Property OrderItem() As WebOrderItem 
     Get 
      Return New WebOrderItem() 
     End Get 
    End Property 
End Class 
+0

Ne yazık ki, bu, örneğin bazı OrderBase öğelerini temsil eden nesnelerin listesini tutun, OrderItem öğesini çağırın ve OrderItemBase'den türetilen bazı nesneler alın. Bununla birlikte, bunu kovaryant arayüzlerle yapabilirdi. – supercat

3

bir yaklaşım korumalı geçersiz kılınabilir yöntemine sahip olmaktır ve sonra ov çağıran bir kamu dışı geçersiz kılınabilir yöntemi vardır: Eğer WebOrder yanı genel bir sınıf olmak istemiyorsanız eril bir tane. Türetilmiş sınıftaki işlevin dönüş değeri değiştiğinde, geçersiz kılınacak yöntemin değiştirilemeyen bir geçersiz kılınması, daha rafine türünü döndüren yeni bir geçersiz kılma yöntemini çağırır ve aynı zamanda genel işlevinin önceki sürümünü, yeni geçersiz kılma. Vb.net bir sınıfın aynı üyeyi geçersiz kılmasına ve gölgelemesine izin verdiyse, işler çok daha temiz olurdu, ancak bunu yapmanın bir yolu yok. Bazı durumlarda

Public Class CarFactory 
    Protected Overridable Function DerivedMakeCar() as Car 
    ' make a car 
    End Function 

    Public Function MakeCar() as Car 
    Return DerivedMakeCar() 
    End Function 

End Class 

Public Class FordFactory 
    Inherits CarFactory 

    Protected Overrides Function DerivedMakeCar() As Car 
    Return DerivedMakeFord() 
    End Function 

    Protected Overridable Function DerivedMakeFord() As Ford 
    ' Make a Ford 
    End Function 

    Public Shadows Function MakeCar() As Ford 
    Return DerivedMakeFord() 
    End Function 

End Class 

daha basit bir alternatif, bir Ford döndüren bir MakeFord() işlevi bulunmaktadır, her zaman tip Car bir nesne döndüren bir halka geçersiz kılınabilir MakeCar() işlev görmekte, bir FordFactory sahip olabilir.

Geçersiz MakeCar() işlevi NotOverridable olur ve sadece MakeFord'u çağırır. Bazı yönlerden, ikinci yaklaşım daha temiz olabilir, ancak ortak bir adlandırma kuralı varsa (örneğin, fabrikalar en türetilen türünü döndüren bir MakeProduct yöntemine sahiptir) gölgeleri kullanmak yararlı olabilir.

İlgili konular