Почему класс C # Может Наследовать от Одного интерфейса Как Неявно, так и Явно?
-
05-07-2019 - |
Вопрос
Сегодня я случайно обнаружил, что один класс C # может наследовать один интерфейс как неявным, так и явным способом.Это меня удивляет.Если C # работает таким образом, то один экземпляр может вести себя по-разному, когда на него ссылаются другим способом.
interface IFoo
{
void DoSomething();
}
class Foo : IFoo
{
#region IFoo Members
public void DoSomething()
{
Console.WriteLine("do something implicitly");
}
#endregion
#region IFoo Members
void IFoo.DoSomething()
{
Console.WriteLine("do something explicitly");
}
#endregion
}
Foo f = new Foo();
f.DoSomething();
((IFoo)f).DoSomething();
Приведенный выше код выполняется и выводится
do something implicitly
do something explicitly
Я считаю, что такой дизайн C # приводит к несогласованности поведения.Возможно, обязательно, чтобы один класс C # мог наследовать от одного интерфейса неявным или неявно выраженным способом, но не от обоих.
Есть ли какая-то причина, по которой C # разработан таким образом?
Решение
Ваш пример не реализует IFoo как явно, так и явно. Вы только явно реализуете IFoo.DoSometing (). В вашем классе есть новый метод, называемый DoSomething (). Он не имеет ничего общего с IFoo.DoSomething, за исключением того, что он имеет то же имя и параметры.
Другие советы
Каждый класс, реализующий интерфейс, имеет отображение между членами этого класса и членами интерфейса.Если класс явно реализует элемент интерфейса, тогда явная реализация будет всегда быть сопоставленным с интерфейсом.Если явной реализации нет, то ожидается неявная реализация, и она будет сопоставлена с интерфейсом.
Когда класс имеет то же имя члена и связанные с ним типы, что и интерфейс но он также явно реализует соответствующий элемент для интерфейса, а затем "неявную" реализацию класса это не так рассмотрена реализация интерфейса вообще (если только это не вызвано явной реализацией).
В дополнение к различным значениям в каждом случае, когда класс реализует несколько интерфейсов с одинаковыми именами / типами членов, даже с одним интерфейсом, сам класс считается, что он имеет неявный интерфейс, который может иметь те же элементы / типы, что и единственный интерфейс, но все же означать что-то другое.
Это делает его более гибким для случаев столкновения. В частности, посмотрите на IEnumerator
и IEnumerator<T>
- оба они имеют свойство Current
, но разных типов , Вы должны использовать явную реализацию интерфейса для реализации обоих (и универсальная форма расширяет неуниверсальную форму).
множественное наследование: Что если вы производите от двух интерфейсов, определяющих один и тот же метод для разных целей?
interface IMoveable
{
public void Act();
}
interface IRollable
{
public void Act();
}
class Thing : IMoveable, IRollable
{
//TODO Roll/Move code here
void IRollable.Act()
{
Roll();
}
void IMoveable.Act()
{
Move();
}
}
Ребята, спасибо за ваши ответы.
Оказывается, что & класс C # может одновременно наследовать один интерфейс как неявным, так и явным образом " на самом деле иллюзия. Фактически, один класс может наследовать один интерфейс за один раз. Р>
В исходном вопросе " DoSomething " Кажется, метод " неявно реализует " интерфейс IFoo (метод фактически генерируется VS2008), но на самом деле это НЕ. С явной реализацией интерфейса IFoo, & Quot; DoSomething & Quot; Метод превращается в обычный метод, который не имеет ничего общего с IFoo, кроме той же сигнатуры.
Я до сих пор считаю, что это сложный дизайн C #, и его легко ошибочно использовать. Скажем, у меня есть такой код
Foo f = new Foo();
f.DoSomething();
Теперь я хочу изменить его код ниже. Кажется, все в порядке, но результат выполнения другой.
Action<IFoo> func = foo => foo.DoSomething();
func(f);