Somut uygulama yerine varsayılan yöntemi nasıl çağırabilirim?


10

C # 8'de Varsayılan Arabirim Yöntemleri davranışı neden değiştirildi? Geçmişte aşağıdaki kod (Varsayılan arayüz yöntemleri demo yayınlanmadığında):

interface IDefaultInterfaceMethod
{
    // By default, this method will be virtual, and the virtual keyword can be here used!
    virtual void DefaultMethod()
    {
        Console.WriteLine("I am a default method in the interface!");
    }

}

interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
    void IDefaultInterfaceMethod.DefaultMethod()
    {
        Console.WriteLine("I am an overridden default method!");
    }
}

class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}

class Program
{
    static void Main()
    {
        IDefaultInterfaceMethod anyClass = new AnyClass();
        anyClass.DefaultMethod();

        IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
        anyClassOverridden.DefaultMethod();
    }
}

aşağıdaki çıktıya sahiptir:

Konsol çıkışı:

Ben arayüzde varsayılan bir yöntemim!
Ben geçersiz kılınmış bir varsayılan yöntemim!

Ancak son C # 8 sürümünde yukarıdaki kod aşağıdaki çıktıyı üretmektedir:

Konsol çıkışı:

Ben geçersiz kılınmış bir varsayılan yöntemim!
Ben geçersiz kılınmış bir varsayılan yöntemim!

Herkes bana bu davranışın neden değiştiğini açıklayabilir?

Not:

IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??

2
Varsayılan arabirim yöntemleri vardı önce ikinci çıkış beklenen durum C # 8. edilir - Bir arabirim yöntemi uygulamak zaman, beklediğiniz o çağrılacak. Belki daha eski bir spesifikasyondan mı bahsediyorsunuz? Bir arabirim yönteminin beklenen davranışını bozduğu için terk edilmesini bekliyorum
Panagiotis Kanavos

3
Daha iyi bir soru "somut uygulama yerine varsayılan yöntemi nasıl arayabilirim?" hangi cevap "henüz olamaz, çünkü base.DefaultMethod () sözdizimi C # 8 düştü"
Panagiotis Kanavos

4
İşte temel çağrıların tartışıldığı ve C # 8 için bırakıldığı tasarım toplantı sayfasıCut base() syntax for C# 8. We intend to bring this back in the next major release. . Bu, düzgün çalışması için çalışma zamanı desteğini gerektirir.
Panagiotis Kanavos

3
Bir arayüz her zaman bir arayüzdür. Bir arabirim yöntemi uyguladığımda, tüm istemcilerin uygulanan yöntemi çağırmasını beklerim. Müşteriler de hangi sınıfın yöntemi uyguladığı umurumda değil - bir arayüze sahipler ve buna diyorlar.
Panagiotis Kanavos

2
Yayınladığınız sözdizimine gelince, bu gerçekten eski bir tekliften olmalı - DIM'ler, açıkça uygulanmış arabirimler gibi yalnızca açıkça çağrılabilir. E ... do açık arabirim sözdizimi kullanır olsa bu öneri karşısında ait virtualI guess? Ve muhtemelen bir miras elmas
Panagiotis Kanavos

Yanıtlar:


6

Daha iyi bir soru olacağını sanıyorum:

Somut uygulama yerine varsayılan yöntemi nasıl çağırabilirim?

Özellik planlandı, ancak Nisan 2019'da C # 8'den kesildi , çünkü verimli bir uygulama çalışma zamanından destek gerektirecektir. Bu, yayınlanmadan önce zamanında eklenemedi. Özelliğin hem C # hem de VB.NET için iyi çalışması gerekir - F # arabirimleri zaten sevmez.

BM çalışma zamanında mevcut değilse, AM () çağrılır. Base () ve arabirimler için bu, çalışma zamanı tarafından desteklenmediği için çağrı bir istisna atar. Çalışma zamanında bunun için destek eklemek istiyoruz, ancak bu sürümü yapmak çok pahalı.

Bazı geçici çözümlerimiz var, ancak istediğimiz davranışa sahip değiller ve tercih edilen kodgen değiller.

C # için uygulamamız tam olarak istediğimiz şekilde olmasa da, biraz işe yarayabilir, ancak VB uygulaması çok daha zor olacaktır. Ayrıca, VB'nin uygulanması, arayüz uygulama yöntemlerinin genel API yüzeyi olmasını gerektirecektir.

Bu çalışacak bir içinden base()çağrı nasıl sınıfları çalışmaya benzer. Teklif örneğiyle işbirliği yapmak:

interface I1
{ 
    void M(int) { }
}

interface I2
{
    void M(short) { }
}

interface I3
{
    override void I1.M(int) { }
}

interface I4 : I3
{
    void M2()
    {
        base(I3).M(0) // What does this do?
    }
}

Cevabı işaretlemeden önce bir süre bırakacağım. belki iyi iş için bazı yukarı oy alacak :-) teşekkür ederim!
Bassam Alugili

1
@BassamAlugili sadece biri bir ay önce benzer bir şey sorduğu için . O zamanlar yine de Why would you do that?. Sonra toplantı dakikalarını öğrendim
Panagiotis Kanavos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.