Bir Arabirimi açıkça veya örtük olarak uygulamak arasındaki fark nedir?


64

Visual Studio'da bir arayüze sağ tıklayabilir ve Arayüz Uygula ya da Açık Arabirim Uygula seçebilirim.

Visual Studio Ekran Görüntüsü

public class Test : ITest
{
    public string Id // Generated by Implement Interface
    {
        get { throw new NotImplementedException(); }
    }

    string ITest.Id // Generated by Implement Interface Explicitly
    {
        get { throw new NotImplementedException(); }
    }
}

İkisi arasında gördüğüm tek fark, eğer Arayüzün Açıkça Uygulanmasını seçerseniz, Arayüz adının arayüz özelliklerine eklenmesi ve oluşturulduklarında metotların kullanılmasıdır.

Bu yöntemin / özelliğin nereden geldiğini görebildiğim için kodu biraz daha okunaklı hale getirdiğini düşünüyorum, ancak bu, sınıfın nasıl kullanıldığı veya derlendiği konusunda herhangi bir fark yaratıyor mu? Arayüzlerimi örtük mü yoksa açıkça mi uyguladığım önemli mi?

Yanıtlar:


51

Check out Andrew Barrett üst cevabı için SO üzerinde "açık olarak arabirim uygulaması vs örtük" .

Temelde:

  • Kapalı: Arayüz yöntemlerine ve özelliklerine, sınıfın bir parçasıymış gibi erişirsiniz.
  • Açık: sınıfı uygulamalı arabirim olarak değerlendirirken yalnızca yöntemlere ve özelliklere erişebilirsiniz.

Kod örnekleri:

örtülü:

Test t = new Test();
t.Id; // OK
((ITest)t).Id; // OK

Açık:

Test t = new Test();
t.Id; // Not OK
((ITest)t).Id; // OK

“Ne zaman” ifadesiyle açıkça bir arabirim uygulamanız gerekir, sınıfınızın zaten arabiriminizin yöntemlerinden biriyle aynı imzayla bir yöntemi olduğu veya sınıfınızın aynı imzalarla yöntemleri paylaşan birkaç arabirim uyguladığı durumdur. fakat uyumsuz sözleşmeler.


1
Ayrıca, güvenli olmayan işlemlerle bir tür "gizli" arayüze sahip olmak için açık bir uygulama buldum. Ayrıca, bu yöntemlere yapılan çağrıları daha fazla öne çıkarır, bu da güvenli olmayan şeyler için iyi bir şeydir.
Tamás Szelei,

Ayrıca, açık arayüzleri kullanmanın bir performans maliyeti olduğunu da belirtmek gerekir, çünkü özelliğe / yönteme başvurduğunuzda nesneyi kutuya / kutunun işaretini kaldırması gerekir. Bu nedenle, mümkünse örtük arabirimler kullanmak daha iyidir
Rachel

3
@Rachel: Performans maliyetinin yalnızca değer türleri için geçerli olduğunu bildiğim kadarıyla.
Groky

8

Yöntemi nasıl adlandırdığınız konusunda da bir fark var.

Bir kullanırken açık arabirim uygulaması, bu belirli uygulaması çağırmak için arayüz türü kullanılmalıdır.

Bu nedenle, arama kodunda ITesterişmek için bir tür değişken kullanmanız gerekir ITest.Id.

MSDN'de Açık Arabirim Uygulaması (C # Programlama Kılavuzu) makalesinin iyi bir örneği vardır.



4

DÜZENLEME: Fark etmemelidir Sınıfınız aynı özelliklere sahip iki arayüzü takmadığı sürece yapmamalısınız , çünkü üyeye erişmeden önce ilgili arayüze aktarmanız gerekir:

public interface ITest
{
    string Id { get; }
}

public interface IAlsoTest
{
    string Id { get; }
}

public interface ITestToo
{
    int Id { get; }
}

public class Test : ITest, IAlsoTest
{
    // Valid implicit implementation of BOTH interfaces
    public string Id
    {
        get { throw new NotImplementedException(); }
    }
}

public class TestSeparately : ITest, ITestToo
{
    // This way we can do different things depending
    // on which interface the callee called from.
    string ITest.Id
    {
        get { throw new NotImplementedException(); }
    }

    int ITestToo.Id
    {
        get { throw new NotImplementedException(); }
    }
}

public class TestOuch
{
    public void DoStuff()
    {
        var ts = new TestSeparately();

        // Works
        Console.WriteLine(((ITest)ts).Id);

        // Works
        Console.WriteLine(((ITestToo)ts).Id);

        // Not valid! Which one did we want to call?
        Console.WriteLine(ts.Id);
    }
}

Örnek kullanım, yalnızca tek bir arabirim kullanıyor olsanız bile (her zaman unutacağım: S) bir arabirim üyesini açıkça uyguladığınızda da geçerli olur; bu nedenle, mümkünse sınıf üyelerini gizleyeceği için, mümkün olduğunda açık uygulamadan kaçınmaya çalışırım. (doğru oldukça kafa karıştırıcı olan) doğru arayüze atılmamak.


3

Jalayan'ın cevabına dayanarak,

  • Kapalı: Arayüz yöntemlerine ve özelliklerine, sınıfın bir parçasıymış gibi erişirsiniz.
  • Açık: sınıfı uygulamalı arabirim olarak değerlendirirken yalnızca yöntemlere ve özelliklere erişebilirsiniz.

görüntü tanımını buraya girin

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.