2009-02-04 25 views
47

uygulamak için bir arabirimin alt sınıflarını belirtin IFoo arabirim var ve IFoo tüm alt sınıflarının Object'in ToString yöntemini geçersiz kılmasını istiyorum. Mümkün mü? tüm alt sınıfları Object uzatmak ve bir uygulama bu şekilde teminToString

interface IFoo 
{ 
    String ToString(); 
} 

beri, bu nedenle derleyici bu konuda şikayet etmiyor:

Basitçe çalışmıyor gibi IFoo için yöntem imza ekleme. Baska öneri?

+0

http: // stackoverflow.com/questions/239408/can-i-force-subclasses-to-override-a-method-without-making-it-abstract <-? aynı? ya da sadece çok benzer? –

cevap

68

Bir arabirim ile yapabileceğinize inanmıyorum. Gerçi bir soyut temel sınıf kullanabilirsiniz:

public abstract class Base 
{ 
    public abstract override string ToString(); 
} 
+0

Zaten onları yazılı hale getirdiğimden beri arayüzler ile sopa umuyordum, sanırım mermiyi ısırmak ve soyut sınıfları değiştirmek zorundayım. Teşekkürler. – rjohnston

+0

Büyük cevap (ve bence tek makul olasılık) ama C# 'in çoklu miras için destek eksikliğiyle ilgili bir dezavantajı var. Base'den miras alması gereken herhangi bir sınıf, başka herhangi bir sınıf dışı sınıftan miras alınamaz Sınıfım: Sınıfım: ThirdPartyClass, Base // mot olası – AlanK

21
abstract class Foo 
{ 
    public override abstract string ToString(); 
} 

class Bar : Foo 
{ 
    // need to override ToString() 
} 
+1

Soru "bunu nasıl bir arayüzle yapabilirim?", "Bunu nasıl yaparım?" , yinede teşekkürler. – rjohnston

0

Ben bu yöntemlerin soyut olmadıkça geçersiz kılma baz sınıfının sanal yöntemlerinden herhangi birine herhangi bir alt sınıfını zorlayabilir sanmıyorum.

1

Bir arabirim yöntemi uygulamak, yöntemi örtük olarak mühürler (ayrıca geçersiz kılar). Öyleyse, aksi belirtilmedikçe, bir arabirimin ilk uygulaması C# 'daki geçersiz kılma zincirini sonlandırır.

Essential .NET

Özet class = arkadaşınız

Kontrol this question

6

Jon & Andrew: soyut hile gerçekten yararlı Yani; Zinciri, onu soyut olarak ilan ederek bitiremeyeceğini bilemedim. Bu cevap vermez biliyorum

public abstract class BaseClass 
{ 
    public abstract string ToStringImpl(); 

    public override string ToString() 
    { 
     return ToStringImpl(); 
    }  
} 
1

: Cheers :)

Geçmişte

ToString() türetilmiş sınıfları geçersiz kılındı ​​edilmesi gereken ettik, hep aşağıdaki gibi bir desen kullandım Sorunuz, ama sorduğunuz şeyi yapmanın bir yolu olmadığından, diğerlerinin görmesi için kendi yaklaşımımı paylaşacağımı düşündüm.

Mark ve Andrew'un önerdiği çözümlerin bir melezini kullanıyorum. Benim uygulamada

, tüm etki alanı varlıklar soyut baz sınıftan türetmek:

public abstract class Entity 
{ 
    /// <summary> 
    /// Returns a <see cref="System.String"/> that represents this instance. 
    /// </summary> 
    public override string ToString() 
    { 
     return this is IHasDescription 
        ? ((IHasDescription) this).EntityDescription 
        : base.ToString(); 
    } 
} 

kendisi sadece basit erişimcisine tanımlar arayüzü:

public interface IHasDescription : IEntity 
{ 
    /// <summary> 
    /// Creates a description (in english) of the Entity. 
    /// </summary> 
    string EntityDescription { get; } 
} 

Yani şimdi bir geri düşmeyi var - veya başka bir deyişle, IHasDescription'u uygulayan Entity numaralı mekanizma EntityDescription'u sağlamalıdır, ancak herhangi bir Entity hala bir dizeye dönüşebilir.

Burada önerilen diğer çözümlerden tamamen farklı olmadığını biliyorum, ancak Entity türünün sorumluluğunu en aza indirgeme fikrini beğeniyorum, böylece açıklama arayüzünü uygulamak isteğe bağlı kalır, ancak Arabirimi uygularsanız, aslında açıklama yöntemini uygulayın.

IMHO, uygulandığı şekliyle "saymak" olmamalıdır object baz sınıfı tarafından uygulanan arabirimler - oh iyi, bunun için bir derleyici seçeneği olması güzel olurdu, ama ...

+0

İkinci bir dökümden kaçınmak için 'yerine 'yerine' yerine' kullanabilirsiniz. – chwarr