2010-04-19 10 views
48

Otrzymuję ten błąd podczas tworzenia metody public dla klasy jawnie implementującej interface. Mam obejście: usuwając jawną implementację metody PrintName. Ale jestem zaskoczony, dlaczego dostaję tego błędu.Błąd kompilacji: "Modyfikator" publiczny "jest nieprawidłowy dla tego elementu" podczas jawnego implementowania interfejsu

Czy ktoś może wyjaśnić błąd?

Kod Biblioteki:

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(); 
    } 
} 

kod dla konsoli testowy Zastosowanie:

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()); 

     } 
    } 
} 

Odpowiedz

61

Podczas korzystania wyraźny wdrożenie interfejsu członkowie są zmuszeni do czegoś bardziej ograniczonym niż prywatnej w samej klasie. A kiedy modyfikator dostępu zostanie wymuszony, nie możesz go dodać.

Podobnie, w samym interfejsie, wszyscy członkowie są publiczny. Jeśli spróbujesz dodać modyfikator w interfejsie, otrzymasz podobny błąd.

Dlaczego jawni członkowie (bardzo) są prywatni? Rozważ:

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. 

Jeśli te metody były publiczne, miałbyś konflikt nazwy, którego nie można rozwiązać za pomocą normalnych reguł przeciążania.

Z tego samego powodu nie można nawet zadzwonić pod numer M() z poziomu członka class C. Będziesz musiał najpierw rzucić this do konkretnego interfejsu, aby uniknąć tej samej niejednoznaczności.

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

(c jak I1) .M(); // nie ma problemu To prawda, ale co jeśli chcesz uzyskać dostęp do metody M poza assambly, to jest niedostępne? – Lalit

+0

@Lalit, jest dostępny wszędzie tam, gdzie I1 jest dostępny. Także w innych zespołach. –

+0

Interfejs I1 jest dostępny poza assambly, ale metoda M dla klasy C jest niedostępna ouuside, sprawdź przeglądarkę klasy, a także jest oznaczona jako prywatna. – Lalit

6

Ty przy wdrażaniu interfejs wyraźnie nie można użyć modyfikatorów dostępu. Użytkownik i tak będzie powiązany z interfejsem, więc nie trzeba określać modyfikatora dostępu, ponieważ wszyscy członkowie interfejsu są zawsze publiczni, do wszystkich jawnie zaimplementowanych członków można uzyskać dostęp tylko za pośrednictwem elementu interfejsu (patrz np. Odpowiedź statichippo).

+0

"Jest to błąd podczas kompilacji dla jawnej implementacji członka interfejsu, który zawiera modyfikatory dostępu, i jest to błąd podczas kompilacji, który uwzględnia modyfikatory abstrakcyjne, wirtualne, nadpisujące lub statyczne." Odpowiednia dokumentacja (http://msdn.microsoft.com/en-us/library/aa664591%28v=VS.71%29.aspx). – R0MANARMY

-2

Kiedy chcemy iść z niejawnym wdrożeniem dla powyższego przykładu, poniższy kod byłby następujący.

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. 
-1

To Explicit wdrożenia, zakres domyślny dla członków interfejsu jest publiczna, podczas gdy jest prywatny w przypadku klasy, ergo, nie ma potrzeby korzystania z modyfikatora publiczną, ponieważ kiedy my nazywamy ta metoda byłaby wywoływana tylko w odniesieniu do interfejsu.

Zgodnie z "MSDN Explicit Interface Implementation" funkcje implementujące jawne interfejsy nigdy nie są jawnie zdefiniowane publicznie.Są domyślnie publiczne. Nie ma sensu definiować ich inaczej.

Powiązane problemy