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

Эквивалент Java 1.6 @Override для интерфейсов в С#

Этот вопрос дает ответ, что Java @Override имеет эквивалент С# ключевого слова override для методов. Однако, поскольку Java 1.6 аннотация @Override также может применяться к интерфейсам.

Практическое применение этого в том, что в Java вы получаете ошибки компиляции, когда класс утверждает, что он реализует метод интерфейса, когда он больше не работает (например, если метод интерфейса удален). Есть ли эквивалентная функциональность в С#?

Некоторые примеры кода:

Java:

public interface A {
  public void foo();
  // public void bar(); // Removed method.
}

public class B implements A {
  @Override public void foo();
  @Override public void bar(); // Compile error
}

С#:

public interface IA {
  void Foo();
  // void Bar(); // Removed method.
}

public class B : A {
  public override void Foo(); // Doesn't compile as not 'overriding' method
  public void Bar(); // Compiles, but no longer implements interface method
}
4b9b3361

Ответ 1

Существует аналогичная функциональность: явная реализация интерфейса.

public interface IA { 
  void foo(); 
  // void bar(); // Removed method. 
} 

public class B : IA { 
  void IA.foo() {}
  void IA.bar() {} // does not compile
} 

Проблема заключается в том, что если вы это сделаете, вы не можете вызвать методы с помощью указателя this (изнутри класса) или через выражение, которое оценивается как B - теперь необходимо отправить в IA.

Вы можете обойти это, создав общедоступный метод с той же подписью и переадресовывая вызов явной реализации следующим образом:

public class B : IA { 
  void IA.foo() { this.foo(); }
  public void foo() {}
} 

Однако это не совсем идеально, и я никогда не видел его на практике.

Ответ 2

Не совсем, хотя VB.Net делает.

Вы можете реализовать метод явно и вызвать обычную общедоступную версию:

public void bar() { ... } 
void IA.bar() { bar(); }

Ответ 3

Как указано, вы не можете получить такой контроль только из интерфейса на С#. Однако вы можете получить его из абстрактного класса. В целях полноты, вот что вы могли бы сделать:

public interface IA
{
    void Foo();
    //void Bar(); - removed
}

public abstract class A : IA
{
    virtual void Foo()
    { }

    // Removed method
    //virtual void Bar()
    //{ }
}

public class B : A
{
    public override void Foo()
    { }

    //throws an error like the one you were receiving regarding no method to override.
    public override void Bar()
    { }
}

Ответ 4

@Override для интерфейса в Java означает "реализует". Когда в Java класс реализует метод интерфейса и эта сигнатура метода изменяется или метод удаляется из интерфейса позже, компилятор java начинает жаловаться на него.

Таким образом, он не позволяет методу стать "мертвым кодом", вам либо нужно удалить аннотацию @Override (поэтому метод станет обычным методом), либо удалите или измените метод, чтобы он соответствовал интерфейсу. Это очень хорошая функция, чтобы ваш код был чистым. Я бы хотел, чтобы у С# тоже была эта функция.

Я использую явное выполнение как можно больше.

Кстати: Resharper показывает это, когда метод реализует метод интерфейса.