Ошибка компиляции: «Модификатор public» недопустим для этого элемента »при явной реализации интерфейса - PullRequest
56 голосов
/ 19 апреля 2010

Я получаю эту ошибку при создании метода 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());

        }
    }
}

Ответы [ 5 ]

68 голосов
/ 19 апреля 2010

При использовании явной реализации интерфейса члены вынуждены использовать нечто более ограниченное, чем 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 
   }
}
11 голосов
/ 19 апреля 2010

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

Customer customer = new Customer();

Console.WriteLine(customer.PrintName());

Нарушает это

7 голосов
/ 19 апреля 2010

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

0 голосов
/ 14 декабря 2017

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

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

0 голосов
/ 14 марта 2016

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

    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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...