Подтвердить что ты не робот

Ошибка компиляции: "Модификатор" public "недействителен для этого элемента", в то время как явно реализует интерфейс

Я получаю эту ошибку при создании метода public для класса для явной реализации interface. У меня есть обходное решение: удалив явную реализацию метода PrintName. Но я удивлен, почему я получаю эту ошибку.

Может кто-нибудь объяснить ошибку?

Код для библиотеки:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test.Lib1
{

    public class Customer : i1 
    {
        public string i1.PrintName() //Error Here...
        {
            return this.GetType().Name + " called from interface i1";
        }
    }

    public interface i1
    {
        string PrintName();
    }

    interface i2
    {
        string PrintName();
    }
}

Код для тестового приложения консоли:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Test.Lib1;

namespace ca1.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer();
            Console.WriteLine(customer.PrintName());

            //i1 i1o = new Customer();
            //Console.WriteLine(i1o.printname());

            //i2 i2o = new Customer();
            //Console.WriteLine(i2o.printname());

        }
    }
}
4b9b3361

Ответ 1

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

Аналогично, в самом интерфейсе все члены public. Если вы попытаетесь добавить модификатор внутри интерфейса, вы получите аналогичную ошибку.

Почему явные члены (очень) частные? Рассмотрим:

interface I1 { void M(); }
interface I2 { void M(); }

class C : I1, I2
{
    void I1.M() { ... }
    void I2.M() { ... }
}

C c = new C();
c.M();         // Error, otherwise: which one?
(c as I1).M(); // Ok, no ambiguity. 

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

По той же причине вы даже не можете вызвать M() изнутри члена class C. Перед тем, как избежать одной и той же двусмысленности, вам придется отбрасывать this на определенный интерфейс.

class C : I1, I2
{
   ...
   void X() 
   {  
     M();             // error, which one? 
     ((I1)this).M();  // OK 
   }
}

Ответ 2

http://msdn.microsoft.com/en-us/library/aa288461(VS.71).aspx: Когда элемент явно реализован, к нему нельзя получить доступ через экземпляр класса, но только через экземпляр интерфейса.

Customer customer = new Customer();

Console.WriteLine(customer.PrintName());

Нарушает это

Ответ 3

Вы не можете использовать модификаторы доступа при явной реализации интерфейса. Член будет привязан к интерфейсу в любом случае, поэтому нет необходимости указывать модификатор доступа, поскольку все члены интерфейса всегда являются общедоступными, и все явно реализованные члены могут быть доступны только через член типа интерфейса (см. например, ответ statichippo).

Ответ 4

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

В соответствии с "" Явная реализация интерфейса MSDN", функции, реализующие явные интерфейсы, никогда явно не определены публично. Они являются общедоступными по умолчанию. Было бы бессмысленно определять их в противном случае.

Ответ 5

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

    interface I1 { void M(); }
interface I2 { void M(); }

class C : I1, I2
{
    public void M() { ... }
}

C c = new C();
c.M();  // Ok, no ambiguity. Because both Interfaces gets implemented with one    method definition.