Почему класс C # Может Наследовать от Одного интерфейса Как Неявно, так и Явно?

StackOverflow https://stackoverflow.com/questions/253058

Вопрос

Сегодня я случайно обнаружил, что один класс 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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top