Когда вы реализуете два интерфейса с одним и тем же методом, как узнать, какой из них вызывается? - PullRequest
4 голосов
/ 18 мая 2011

Если у вас есть TheMethod() в интерфейсах I1 и I2 и следующий класс

class TheClass : I1, I2
{
    void TheMethod()
}

Если что-то создает экземпляр TheClass, как он узнает, какой интерфейс он использует?

Ответы [ 8 ]

7 голосов
/ 18 мая 2011

Если именно так клиентский код использует класс, это не имеет значения. Если ему нужно сделать что-то специфическое для интерфейса, он должен объявить интерфейс, который ему нужен, и назначить класс, например,

I1 i = new TheClass()
i.TheMethod();

Конечно, используя вашу текущую реализацию TheClass, не имеет значения, если объявлено i как I1 или I2, поскольку у вас есть только одна реализация.

Если вы хотите отдельную реализацию для интерфейса, вам нужно создать явные реализации ...

    void I1.TheMethod()
    {
        Console.WriteLine("I1");
    }

    void I2.TheMethod()
    {
        Console.WriteLine("I2");
    }

Но имейте в виду, что явные реализации не могут быть публичными. Вы можете явно реализовать только одно, а другое оставить по умолчанию, которое может быть общедоступным.

    void I1.TheMethod()
    {
        Console.WriteLine("I1");
    }

    public void TheMethod()
    {
        Console.WriteLine("Default");
    }

Посмотрите статью MSDN для более подробной информации.

5 голосов
/ 18 мая 2011

Если оба метода общедоступны, то будет вызываться один и тот же метод независимо от того, к какому интерфейсу он был вызван. Если вам нужно больше детализации, вам нужно использовать явные реализации интерфейса:

class TheClass : I1, I2
{
    void I1.TheMethod() {}
    void I2.TheMethod() {}
}

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

TheClass theClass = new TheClass();
I1 i1 = theClass;
I2 i2 = theClass;

i1.TheMethod();  // (calls the first one)
i2.TheMethod();  // (calls the other one)

Следует иметь в виду, что если вы сделаете обе реализации явными, вы больше не сможете вызывать TheMethod для переменных, объявленных как TheClass:

theClass.TheMethod();   // This would fail since the method can only be called on the interface

Конечно, если хотите, вы можете сделать явной только одну из реализаций, а другую оставить открытой, и в этом случае вызовы TheClass вызовут публичную версию.

3 голосов
/ 18 мая 2011

Вы не используете интерфейс в смысле его вызова.Интерфейс - это просто контракт, определяющий, какие методы вы можете вызвать по существу.Вы всегда вызываете реализацию.

2 голосов
/ 18 мая 2011

Если вы создаете экземпляр класса, то вы не используете ни один из интерфейсов. Если вы приведете ссылку на любой интерфейс, то вы используете этот интерфейс. Пример:

TheClass c = new TheClass();
c.TheMethod(); // using the class

I1 i = new TheClass();
i.TheMethod(); // using the I1 interface

Поскольку ваш класс объявлен, оба интерфейса будут использовать один и тот же метод. Вы также можете указать методы для класса и отдельных интерфейсов:

class TheClass : I1, I2
{
  void TheMethod() {} // used by the class
  void I1.TheMethod() {} // used by the I1 interface
  void I2.TheMethod() {} // used by the I2 interface
}

Если вы укажете только методы для интерфейсов, вы не сможете получить доступ к методу, если сначала не приведете ссылку на интерфейс:

class TheClass : I1, I2
{
  void I1.TheMethod() {} // used by the I1 interface
  void I2.TheMethod() {} // used by the I2 interface
}

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

class TheClass : I1, I2
{
  void TheMethod() {} // used by the class and the I1 interface
  void I2.TheMethod() {} // used by the I2 interface
}
1 голос
/ 18 мая 2011

Пока сигнатуры методов одинаковы, для метода вполне законно реализовывать методы двух или более интерфейсов.

Нет способа узнать, "через какой интерфейс" методназывается - такого понятия нет (и это не имеет значения).

0 голосов
/ 30 мая 2016
public interface IA
{
   void Sum();
}

public interface IB
{
    void Sum();
}

public class SumC : IA, IB
{
   void IA.Sum()
    {
        Console.WriteLine("IA");
    }

   void IB.Sum()
   {
       Console.WriteLine("IB");
   }
  public void Sum()
   {
       Console.WriteLine("Default");
   }
}

public class MainClass
{
    static void Main()
    {
        IA objIA = new SumC();
        IB objIB = new SumC();
        SumC objC = new SumC();

        objIA.Sum();
        objIB.Sum();
        objC.Sum();

        Console.ReadLine();
    }
}
0 голосов
/ 18 мая 2011

Это не имеет значения. Приведение к любому из интерфейсов приведет к вызову метода, но поскольку интерфейс не может содержать код, вы не можете наследовать поведение от него.

0 голосов
/ 18 мая 2011

Реальный вопрос: «Кому какое дело, какой интерфейс он использует?»На самом деле, он не использует интерфейс вообще.Он использует реализацию для выполнения интерфейса.

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