Подтвердить что ты не робот

Почему я не могу вызвать методы внутри класса, который явно реализует интерфейс?

Вот история. Я создал интерфейс, IVehicle. Я явно реализовал интерфейс в своем классе, Vehicle.cs.

Вот мой интерфейс:

Interface IVehicle
{
        int getWheel();
}

вот мой класс:

class Vehicle: IVehicle
{

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine(getWheel());
     }
}

Обратите внимание, что getWheel() явно реализовано. Теперь, когда я пытаюсь вызвать этот метод в классе Vehicle, я получаю сообщение об ошибке, указывающее, что getWheel() не существует в текущем контексте. Может кто-нибудь помочь мне понять, что я делаю неправильно?

4b9b3361

Ответ 1

Когда вы явно реализуете интерфейс, вам сначала нужно передать объект в интерфейс, затем вы можете вызвать метод. Другими словами, метод доступен, только если метод вызывается на объекте как тип интерфейса, а не как конкретный тип.

class Vehicle: IVehicle {

     public int IVehicle.getWheel()
     {
         return wheel;
     }

     public void printWheel()
     {
         Console.WriteLine( ((IVehicle)this).getWheel() );
     }
}

Для получения дополнительной информации см. эту ссылку в MSDN. Вот соответствующий фрагмент:

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

Для чего это стоит - это, вероятно, не особенно хорошо использует явную реализацию интерфейса. Как правило, вы хотите использовать явную реализацию, когда у вас есть класс, который имеет полный интерфейс для типичных операций, но также реализует интерфейс, который может замещать некоторые из этих операций. Канонический пример - это класс File, реализующий IDisposable. Он должен иметь метод Close(), но должен быть реализован Dispose(). При обработке File используйте Open/Close. Однако, если он открыт в операторе using, он будет рассматривать его как IDisposable и вызывает Dispose. В этом случае Dispose просто вызывает Close. Вы не обязательно должны показывать Dispose как часть реализации File, поскольку такое же поведение доступно из Close.

Ответ 2

Согласно MSDN:

Можно реализовать член интерфейса явно создает член класса, который называется только через интерфейс, и является специфическим к этому интерфейсу.

И в Спецификации языка С#:

Невозможно получить доступ к явный член интерфейса реализации в полном объеме квалифицированное имя в вызове метода, доступа к ресурсам или доступа индексатора. явный член интерфейса реализация может быть доступна только через экземпляр интерфейса и в этом случае, просто имя участника.

Чтобы получить доступ к этому члену, вы можете сначала передать класс в интерфейс, а затем получить к нему доступ.

Ответ 3

Чтобы избежать множества раздражающих бросков на вашем классе, вы можете создать указатель как тип интерфейса

public class Foo : IBar
{
    readonly IBar bar;
    public Foo()
    {
       bar = this;
    }
}

А затем вызовите участников, используя bar.