2010-06-03 3 views
1

Извините за неопределенное название, но я не уверен, что это называется.Код Visual Studio, созданный при выборе явного интерфейса интерфейса

Скажите, что я добавляю IDisposable в мой класс, Visual Studio может создать для меня метод stub. Но это создает окурок, как:

void IDisposable.Dispose()

Я не понимаю, что делает этот синтаксис. Почему это так, а не public void Dispose()?

И с первым синтаксисом я не мог понять, как вызвать Dispose() из моего класса (в моем деструкторе).

ответ

2

Когда вы явно реализуете элемент интерфейса, что делает сгенерированный код, вы не можете получить доступ к элементу через экземпляр класса. Вместо этого вы должны вызвать его через экземпляр интерфейса. Например:

class MyClass : IDisposable 
{ 
    void IDisposable.Dispose() 
    { 
    // Do Stuff 
    } 

    ~MyClass() 
    { 
    IDisposable me = (IDisposable)this; 
    me.Dispose(); 
    } 
} 

Это позволяет реализовать два интерфейса с членом одного и того же имени и явно вызвать любого члена независимо друг от друга.

interface IExplict1 
{ 
    string InterfaceName(); 
} 

interface IExplict2 
{ 
    string InterfaceName(); 
} 

class MyClass : IExplict1, IExplict2 
{ 
    string IExplict1.InterfaceName() 
    { 
    return "IExplicit1"; 
    } 

    string IExplict2.InterfaceName() 
    { 
    return "IExplicit2"; 
    } 
} 

public static void Main() 
{ 
    MyClass myInstance = new MyClass(); 

    Console.WriteLine(((IExplcit1)myInstance).InstanceName()); // outputs "IExplicit1" 

    IExplicit2 myExplicit2Instance = (IExplicit2)myInstance; 

    Console.WriteLine(myExplicit2Instance.InstanceName()); // outputs "IExplicit2" 
} 
1

Visual Studio дает вам два варианта:

  • Реализовать
  • Реализовать Явный

Вы обычно выбираете первый (без явного): что дает вам поведение, которое вы хотите.

«Явный» вариант полезен, если вы наследуете один и тот же метод от двух разных интерфейсов, т. Е. Множественного наследования (обычно это не так).

1

Члены типа интерфейса всегда открыты. Для этого необходимо, чтобы их реализация была общедоступной. Это не составляет, например:

interface IFoo { void Bar(); } 

class Baz : IFoo { 
    private void Bar() { } // CS0737 
} 

Явная реализация интерфейса обеспечивает синтаксис, который позволяет метод быть частным:

class Baz : IFoo { 
    void IFoo.Bar() { } // No error 
} 

Классическим использовать для этого, чтобы скрыть реализацию базового интерфейса тип. IEnumerable <> будет очень хороший пример:

class Baz : IEnumerable<Foo> { 
    public IEnumerator<Foo> GetEnumerator() {} 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { } 
} 

Обратите внимание, как общая версия доступна, то необщая версия скрыта. Это и препятствует его использованию, и позволяет избежать ошибки компиляции из-за дублирования метода.


В вашем случае неправильная реализация утилиты() явно неверна. Вы написали Dispose(), чтобы клиентский код вызывал его, заставляя его отличать от IDisposable, чтобы сделать вызов, не имеет смысла.

Кроме того, вызов Dispose() из финализатора является запахом кода. Стандартный шаблон заключается в добавлении защищенного метода Dispose (bool disposing) в ваш класс.

Смежные вопросы