C #: интерфейс: тот же метод в 2 интерфейсах - PullRequest
1 голос
/ 10 июля 2011

У меня есть 2 интерфейса как,

    public interface I1
    {
       string GetRandomString();
    }

   public interface I2
   {
      string GetRandomString();
   }

и в классе я имплантировал оба,

    public class ClassA : I1, I2
    {

      string I1.GetRandomString()
      {
         return "GetReport I1";
      }

      string I2.GetRandomString()
      {
          return "GetReport I1";
       }

    }

Теперь в основном методе я хочу получить доступ, эти методы интерфейса, ноне могу

    static void Main(string[] args)
    {
        var objClassA = new ClassA();
        objClassA.GetRandomString(); // not able to do this, comile time error ... 
    }

Я знаю, что мне не хватает некоторых базовых OOPS, просто хотел это знать.любая помощь ?

Ответы [ 7 ]

4 голосов
/ 10 июля 2011

Вы можете привести объект к требуемому типу интерфейса и затем вызвать метод.

if (objClassA is I1)
{
    ((I1)objClassA).GetRandomString();
}
if (objClassA is I2)
{
    ((I2)objClassA).GetRandomString();
}
4 голосов
/ 10 июля 2011

Проблема в том, что эти функции не являются функциями-членами MyClass, потому что они определены и I1.GetRandomString как I2.GetRandomString.Вы можете вызывать их только на одном из интерфейсов:

    I1 objClassA = new ClassA();
    objClassA.GetRandomString();

или

    I2 objClassA = new ClassA();
    objClassA.GetRandomString();
3 голосов
/ 12 июля 2011

Если вам иногда захочется использовать один интерфейс, а иногда и другой, вероятно, будет необходимо использовать приведение для, наконец, одного из них.Если вы управляете типом и можете иметь одну из функций интерфейса доступной напрямую, а не как явную реализацию, это позволит избежать требования приведения к этой функции.Чтобы избежать необходимости настраивать любую из этих функций, вы должны сделать их доступными под разными именами внутри объекта.Поскольку в C # любой метод, реализующий anyInterface.Boz, должен называться Boz, лучше всего подходить к тому, чтобы реализации IFoo.Boz и IBar.Boz просто вызывали публичные методы с именами FooBoz и BarBoz, которые затем можно было бы вызывать «напрямую» безнеоднозначность.

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

    public interface AliceFoo { void foo();};
    public interface BobFoo { void foo();};
    static void do_alice_foo<T>(ref T it) where T:AliceFoo
    {
        it.foo();
    }
    static void do_bob_foo<T>(ref T it) where T : BobFoo
    {
        it.foo();
    }

Этот подход позволяет использовать любой метод 'foo' без необходимости что-либо вводить.

2 голосов
/ 10 июля 2011

Вы должны привести ваш объект к определенному типу интерфейса.

static void Main(string[] args)
{
    var objClassA = new ClassA();

    I1 objClassAThreatedAsI1Interface = (I1)objClassA;
    objClassAThreatedAsI1Interface.GetRandomString();

    I2 objClassAThreatedAsI2Interface = (I2)objClassA;
    objClassAThreatedAsI2Interface.GetRandomString();
}
1 голос
/ 10 июля 2011

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

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

Или, лучше, выберите один из интерфейсов в качестве «основного» интерфейса и не указывайте явную реализацию.

т.е.

public class ClassA : I1, I2
{
    // make I1's implementation the "main" one
    public string GetRandomString()
    {
        return "GetReport I1";
    }

    // I2's implementation could only be called via a reference to an I2
    string I2.GetRandomString()
    {
        return "GetReport I2";
    }

}

В качестве альтернативы, просто используйте одну реализациюметода (и пропустить явные реализации).

0 голосов
/ 10 июля 2011

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

Если вы просто хотите, чтобы в вашем классе была определена одна версия метода, удалите явное определение интерфейса (другими словами, удалите I1. Из первого определения функции и весь метод I2. * Полностью). )

0 голосов
/ 10 июля 2011

Отметьте два ваших метода GetRandomString как общедоступные в ClassA. Если вы не предоставите модификатор доступа, по умолчанию он будет закрытым.

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