2010-04-01 16 views
50

Ok, quindi questa potrebbe essere una domanda stupida, e c'è sicuramente la risposta ovvia, ma ero curioso di sapere se mi sono perso qualche sottigliezza qui.Membri pubblici e interni in una classe interna?

C'è qualche differenza in termini di visibilità/usabilità tra un membro public dichiarato in una classe e di una internalinternal membro dichiarato in una classe internal?

cioè tra

internal class Foo 
{ 
    public void Bar() 
    { 
    } 
} 

e

internal class Foo 
{ 
    internal void Bar() 
    { 
    } 
} 

Se hai dichiarato il metodo come public ed anche virtual, e poi a sovrascrivere in una classe derivata che è public, la ragione per l'utilizzo di questo modificatore è chiaro. Tuttavia, questa è l'unica situazione ... mi manca qualcos'altro?

+2

_Se hai dichiarato il metodo come pubblico e anche virtuale, quindi lo hai annullato in una classe derivata che è public_ ** meeeep! **: non ti è consentito aumentare la visibilità, solo il contrario: puoi creare un classe derivata di una classe pubblica che è interna (o anche nidificata e privata) – springy76

+2

I googler prendono nota: questa quasi duplicata [domanda] (http://stackoverflow.com/questions/9302236/why-use-a-public-method -in-an-internal-class/9302642 # 9302642) contiene un'altra risposta particolarmente eccellente. –

risposta

47

Consideriamo questo caso:

public interface IBar { void Bar(); } 
internal class C : IBar 
{ 
    public void Bar() { } 
} 

Qui C.Bar non può essere contrassegnato come interno; In questo modo è un errore perché C.Bar si può accedere da un chiamante di D.GetBar():

public class D 
{ 
    public static IBar GetBar() { return new C(); } 
} 
+1

Grazie Eric, questo è un altro buon caso. L'implementazione dell'interfaccia e l'ereditarietà della classe sono quindi le ragioni per cui si consente il modificatore 'public' o' internal' in una classe 'internal'. In altri casi, sembrano equivalenti. – Noldorin

+8

Eric risponde anche a una domanda quasi identica all'indirizzo: http://stackoverflow.com/a/9302642/398015 Ci sono ulteriori dettagli nel suo post che aggiungono sostanza considerevole alla risposta di cui sopra. – Chris

0

public membri di una classe internal possono ignorare public membri del public classi base e, quindi, essere un po 'più esposta ... se indirettamente.

29

A internal membro è ancora solo internal in una classe internal.

From MSDN:

The accessibility of a member can never be greater than the accessibility of its containing type. For example, a public method declared in an internal type has only internal accessibility

pensare in questo modo, vorrei accedere a una proprietà public su ....? Una classe che non riesco a vedere? :)

La risposta di Eric è molto importante in questo caso, se è esposta tramite un'interfaccia e non direttamente, fa fa la differenza, dipende solo se ci si trova in quella situazione con il membro con cui si ha a che fare.

+0

Sì, questo era esattamente il mio pensiero tranne nel caso in cui Eric ha sottolineato (oltre a quello della mia domanda iniziale). – Noldorin

+0

Fa anche la differenza quando si usa il riflesso. I metodi privi di parametro come Type.GetMethods() restituiscono solo membri pubblici. E il metodo pubblico all'interno della classe interna sa ancora che è pubblico. – springy76

+1

"L'accessibilità di un membro non può mai essere maggiore dell'accessibilità del suo tipo di contenuto." Mentre ciò è vero per alcuni casi, un membro 'public' di una classe' private' è chiaramente un ambito più ampio di un membro 'privato' di una classe' private' (il primo è un progetto esteso, essendo quest'ultimo solo di classe). – Deanna

1

Se si tratta di riflessione è importante se il socio è pubblico o meno:

Per esempio potresti anche passare una classe privata nidificata a un bind WPF e l'associazione funzionerebbe contro le proprietà pubbliche proprio come al solito.

1

Di fronte a un altro esempio in cui è differenza tra questi due, quando utilizzato da XAML in WPF.

XAML:

<Button Tag="{x:Static vm:Foo+Bar.e1}" /> 

codice con internal enum compila con successo:

internal class Foo 
{ 
    internal enum Bar 
    { 
     e1, 
     e2, 
    } 
} 

Ma sorprendentemente a cambiarlo con public risultati in errore:

internal class Foo 
{ 
    public enum Bar 
    { 
     e1, 
     e2, 
    } 
} 

L'ultimo esempio produce errore di compilazione :

error MC3064: Only public or internal classes can be used within markup. 'Bar' type is not public or internal.

Sfortunatamente, non posso spiegare cosa c'è che non va con public in questo caso. La mia ipotesi è "solo perché WPF funziona in questo modo". Basta modificare il modificatore della classe nidificata su internal per eliminare l'errore.

+0

Grazie per questo! Non indovinerei mai cosa c'era di sbagliato nel mio XAML – torvin

Problemi correlati