Come implementare i membri delle interfacce interne
Domanda
Sto rifattorizzando la base di codice del progetto in cui mi trovo attualmente in modo che le classi / interfacce che non siano utili oltre i confini dell'assemblaggio debbano essere dichiarate come interne (piuttosto che pubbliche). Ma ho riscontrato un problema con il seguente codice:
internal interface IFirstInterface
{
...
}
internal interface ISecondInterface
{
IFirstInterface First{ get; }
...
}
public class Implementer : ISecondInterface
{
public IFirstInterface First {get; private set;}
...
}
Le mie domande:
-
Perché i membri delle interfacce interne devono essere implementati pubblicamente? Se si implementa l'interfaccia su una classe interna, i membri implementati non dovrebbero essere interni? Questo non è un grosso problema poiché i membri dell'interfaccia non saranno comunque accessibili pubblicamente, dato che la classe è interna. Sembra contro intuitivo.
-
Il problema principale è con lo scenario sopra dato che non posso avere un getter pubblico per IFirstInterface poiché è presumibilmente un'interfaccia interna, cioè ottengo il seguente errore dal compilatore:
Accessibilità incoerente: proprietà digitare "IFirstInterface" è inferiore accessibile rispetto alla proprietà 'Implementer.First'
C'è un modo per aggirare questo?
Nota : mi rendo conto che probabilmente c'è poco valore in questo esercizio di refactoring, ma ho pensato che sarebbe stato un buon modo per capire meglio le implicazioni del modificatore interno.
Soluzione
Solo da notare: il codice che hai effettivamente fornito viene compilato , poiché Implementer
è una classe interna. Il problema si presenta quando Implementer
è pubblico.
Il modo per aggirare questo è usare l'implementazione esplicita dell'interfaccia:
public class Implementer : ISecondInferface
{
private IFirstInterface first;
IFirstInterface ISecondInterface.First { get { return first; } }
}
Non puoi avere il setter lì dentro, perché stai implementando esplicitamente l'interfaccia che non definisce il setter. potresti farlo in alternativa:
public class Implementer : ISecondInterface
{
internal IFirstInterface First { get; private set; }
IFirstInterface ISecondInterface.First { get { return First; } }
}
È un peccato che le interfacce interne abbiano membri pubblici - ciò complica cose come questa. Sarebbe strano per un'interfaccia pubblica avere un membro interno (che cosa sarebbe interno - l'implementatore o il dichiaratore?) Ma per le interfacce interne ha molto più senso.
Altri suggerimenti
Perché i membri delle interfacce interne devono essere implementati pubblicamente?
Quando si definisce un'interfaccia, non si definisce il livello di accesso per i membri, poiché tutti i membri dell'interfaccia sono public
. Anche se l'interfaccia in quanto tale è interna
, i membri sono comunque considerati public
. Quando si effettua un'implementazione implicita di tale membro, la firma deve corrispondere, quindi deve essere public
.
Per quanto riguarda l'esposizione del getter, suggerirei invece di realizzare un'implementazione esplicita dell'interfaccia e di creare una proprietà interna
per esporre il valore:
internal IFirstInterface First { get; private set; }
IFirstInterface ISecondInterface.First
{
get { return this.First; }
}
So che questo post ha qualche anno, ma penso che valga la pena notare che puoi implementare un'interfaccia interna su una classe pubblica, vedi i seguenti link:
http://forums.create.msdn.com/forums/p/29808/ 167820.aspx
http://msdn.microsoft.com/en-us/ biblioteca / aa664591% 28VS.71% 29.aspx
Un esempio dal primo link:
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"; }
}
}