2009-08-03 14 views
19

Reaktoryzuję bazę kodu projektu, nad którym obecnie pracuję, aby klasy/interfejsy, które nie są użyteczne poza ograniczeniami zespołu, powinny być zadeklarowane jako wewnętrzne (a nie publiczne) . Ale ja napotkasz problem z następującego kodu:Jak zaimplementować elementy interfejsów wewnętrznych?

internal interface IFirstInterface 
{ 
    ... 
} 

internal interface ISecondInterface 
{ 
    IFirstInterface First{ get; } 
    ... 
} 

public class Implementer : ISecondInterface 
{ 
    public IFirstInterface First {get; private set;} 
    ... 
} 

moje pytania:

  1. Dlaczego członkowie interfejsów wewnętrznych muszą być publicznie wdrożony? Jeśli implementujesz interfejs na wewnętrznej klasie, czy członkowie nie powinni być wewnętrzni? Nie jest to duży problem, ponieważ członkowie interfejsu i tak nie będą publicznie dostępni, ponieważ klasa jest wewnętrzna. Po prostu wydaje się to sprzeczne z intuicją.

  2. Głównym problemem jest to, ze scenariuszem powyżej ponieważ nie mogę mieć getter publicznego dla IFirstInterface ponieważ jest rzekomo wewnętrzna czyli interfejs pojawia się następujący komunikat o błędzie z kompilatora:

Niekonsekwetne dostępności : własność typu 'IFirstInterface' jest mniej dostępny niż własności 'Implementer.First'

Czy Ther e w inny sposób?

Uwaga: Zdaję sobie sprawę, że nie ma chyba trochę wartość w tym refactoring ćwiczenia, ale myślałem, że będzie to dobry sposób dla mnie głębiej rozumieć konsekwencje wewnętrznego modyfikatora.

+0

Jeśli jej rozwiązaniem, można obejść ograniczenia metody interfejsu jest publiczny za pomocą abstrakcyjnej klasy bazowej zamiast. –

Odpowiedz

45

Po prostu zwróć uwagę - kod, który podałeś, , kompiluje, ponieważ jest klasą wewnętrzną. Problem pojawia się, gdy Implementer jest publiczny.

Runda to sposobem jest użycie wyraźny wdrożenie interfejsu:

public class Implementer : ISecondInferface 
{ 
    private IFirstInterface first; 
    IFirstInterface ISecondInterface.First { get { return first; } } 
} 

nie można mieć ustawiająca się tam, bo jesteś jawnie wykonawczych interfejsu, który nie definiuje setter. Ci mógłby to zrobić jako alternatywę:

public class Implementer : ISecondInterface 
{ 
    internal IFirstInterface First { get; private set; } 
    IFirstInterface ISecondInterface.First { get { return First; } } 
} 

To niefortunne, że interfejsy wewnętrzne członków publicznych - to nie komplikować rzeczy jak ta. Byłoby dziwne, gdyby interfejs publiczny miał wewnętrzny element (do czego byłby on wewnętrzny - implementator lub deklarator?), Ale w przypadku interfejsów wewnętrznych ma o wiele więcej sensu.

+0

Ah, poprawne. Będę edytować moje pytanie, aby było mniej mylące dla czytelników. Dzięki! – jpoh

10

Dlaczego członkowie wewnętrznych interfejsów muszą być publicznie wdrażane?

Podczas definiowania interfejsu, nie określają poziom dostępu dla członków, ponieważ wszyscy członkowie interfejsu są public. Nawet jeśli interfejs jako taki to internal, członkowie nadal są uznawani za public. W przypadku niejawnej implementacji takiego członka podpis musi być zgodny, więc musi to być public.

chodzi o eksponowanie getter, chciałbym zaproponować dokonanie wyraźny implementacji interfejsu zamiast oraz tworzenie własności internal narażać wartość:

internal IFirstInterface First { get; private set; } 

IFirstInterface ISecondInterface.First 
{ 
    get { return this.First; } 
} 
7

Znam ten post jest kilka lat, ale myślę, że warto zauważyć, że można wdrożyć wewnętrzny interfejs na publicznej klasy, patrz poniższe linki:

http://forums.create.msdn.com/forums/p/29808/167820.aspx
http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx

Przykład z pierwszego linku:


internal interface ISecretInterface 
{ 
    string Property1 { get; } 
} 

public class PublicClass : ISecretInterface 
{ 
    // class property 
    public string Property1 
    { 
     get { return "Foo"; } 
    } 

    // interface property 
    string ISecretInterface.Property1 
    { 
     get { return "Secret"; } 
    } 
} 
+0

Jak twoja odpowiedź z 2011 roku różni się od dwóch odpowiedzi z 2009 roku? –

+2

Szczerze mówiąc nie wiem i mogę zobaczyć, dlaczego dodałem go, chociaż pamiętam, jak to robię. To nic nie dodaje i próbowałem to rozgryźć, patrząc na historię wersji, aby sprawdzić, czy jest jakaś wskazówka, ale wciąż nic. Może miałam głupi dzień. – Robert

+0

Z jakiegoś powodu ta odpowiedź jest łatwiejsza do skonsumowania niż wcześniejsze, ponieważ wyjaśnienie na początku odpowiedzi odnosi się do mojej sytuacji i pasuje do tego, co wyszukałem. Dziękuję za wyraźne stwierdzenie, że klasy publiczne mogą implementować wewnętrzne interfejsy w łatwy do zużycia sposób ;-). – binki