Почему я получаю ошибку в C # при смешении явной реализации и полиморфизма? - PullRequest
0 голосов
/ 02 апреля 2009

Я получаю эту ошибку:

Тип Bar не реализует интерфейс IFoo

Из этого кода:

public interface IFoo
{
   void DoA();

   void DoB();
}

public class Foo:IFoo
{

    void IFoo.DoA()
    {

    }

    void IFoo.DoB()
    {


   }
}

public class Bar:Foo
{

     void IFoo.DoA()
      {
          base.doA();

      }

      void IFoo.DoB()
      {
          base.doB();

      }
  }  

Я использую C # 2.0.

Что я делаю не так?

Ответы [ 5 ]

3 голосов
/ 02 апреля 2009
public class Bar : Foo, IFoo
{ 
    // Your code
}
2 голосов
/ 02 апреля 2009

Я тоже столкнулся с этим. что «хуже», в зависимости от того, как вы на это смотрите, вы не можете определить виртуальные реализации интерфейса, которые будут переопределены в дочерних классах. Я приобрел привычку делать это:

public class Foo:IFoo
{    
     void IFoo.DoA()
     {
          DoACore();
     }
     void IFoo.DoB()
     {
          DoBCore();
     }
     protected virtual void DoACore()
     {
     }
     protected virtual void DoBCore()
     {
     }
}
public class Bar:Foo
{     protected override void DoACore()
      {
          base.DoACore();
      }
      protected override void DoBCore()
      {
          base.DoBCore();
      }
}
2 голосов
/ 02 апреля 2009

См. ответ n8wrl о том, как должен делать это. См. Ниже причину, по которой.

Вы не можете реализовать элементы интерфейса Explicity (void IFoo.DoA()), когда неявно реализуете интерфейс. Другими словами, поскольку Bar реализует IFoo только за счет расширения Foo, вы не можете использовать явную реализацию.

Это будет работать:

public class Bar : Foo
{
    public void DoA()
    {
        ...
    }

    public void DoB()
    {
        ...
    }

Или это:

public class Bar : Foo, IFoo
{
    void IFoo.DoA()
    {
        ...
    }

    void IFoo.DoB()
    {
        ...
    }

Большая проблема, с которой вы, вероятно, столкнетесь, заключается в том, что, поскольку Foo не является абстрактным, он должен реализовывать DoA и DoB. Если вы также реализуете эти методы в bar, вы не будете делать это полиморфно. Вы будете скрывать реализации Foo, если код имеет дескриптор типа Bar.

1 голос
/ 03 апреля 2009

Сначала не понятно, в чем задача? Если цель состояла в том, чтобы решить проблему как можно скорее, то «Bar: Foo, IFoo» - самое короткое решение.

Если вы просто пытаетесь узнать «неявную / явную» разницу в интерфейсах, тогда отметьте этот пост .

Также обратите внимание, что «n8wrl» решение спорно. Это нормально, только если Foo действительно требует явной реализации IFoo. Если нет, то есть более простой способ:

public interface IFoo
{
    void DoA();
}

public class Foo : IFoo
{
    public virtual void DoA() {}
}

public class Bar : Foo
{
    public override void DoA() {}
}

Надеюсь, это поможет.

1 голос
/ 02 апреля 2009

Я подозреваю, что возникает путаница в отношении того, как интерфейсы были реализованы в C ++, как абстрактные классы и множественное наследование.

В .NET интерфейс - это просто контракт, в котором говорится, что вы будете реализовывать эти методы.

Ваш код не будет компилироваться по той же причине, по которой этот код не будет компилироваться (это было бы с C ++):

public interface IFoo
{
    void DoSomething();
}

public abstract class Foo : IFoo
{
}

Foo заявляет, что Foo реализует IFoo, больше ни о ком не говорит.

Если вы хотите заставить производные классы реализовать его, вы должны сделать:

public interface IFoo
{
    void DoSomething();
}

public abstract class Foo : IFoo
{
    public abstract void DoSomething();
}

Или, если вы действительно хотите, чтобы интерфейсные методы были скрыты явной реализацией, то что-то вроде n8wrl, опубликованное выше.

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