Эквивалент Java 1.6 @ Override для интерфейсов в C # - PullRequest
14 голосов
/ 20 января 2012

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

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

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

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
}

C #:

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
}

Ответы [ 4 ]

8 голосов
/ 20 января 2012

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

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() {}
} 

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

1 голос
/ 20 января 2012

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

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()
    { }
}
1 голос
/ 20 января 2012

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

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

public void bar() { ... } 
void IA.bar() { bar(); }
0 голосов
/ 22 декабря 2012

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

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

Я использую явную реализацию столько, сколько могу.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...