Эквивалент 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
}
Ответы
Ответ 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 показывает это, когда метод реализует метод интерфейса.