Una interfaz es un contrato. Dice "Puedo hacer estas cosas". ¿De qué sirve que alguien le entregue una instancia de IInterface
en la que no puede usar algunos de los métodos de ese contrato porque no se han marcado como públicos?
Esta es la razón fundamental para diseñar el lenguaje de esta manera. La especificación para esto está en §13.2 de la especificación de idioma:
Todos los miembros de la interfaz tienen acceso público implícitamente. Es un error de tiempo de compilación para las declaraciones de los miembros de la interfaz para incluir cualquier modificador. En particular, los miembros de las interfaces no pueden ser declarados con los modificadores abstract
, public
, protected
, internal
, private,
virtual
, override
o static
.
En cuanto a su código, este es un ejemplo de explicit interface implementation. Es más útil cuando una clase o estructura implementa dos interfaces, cada una con un miembro con la misma firma. Por ejemplo, tanto IEnumerable
como IEnumerable<T>
definen un método GetEnumerator
que no acepta parámetros.
public interface IEnumerable {
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable {
IEnumerator<T> GetEnumerator();
}
Tenga en cuenta que por las definiciones anteriores, cualquier clase que implemente IEnumerable<T>
también debe implementar IEnumerable
. Tenga en cuenta que el tipo de devolución no forma parte de la firma y, por lo tanto, tenemos un conflicto con IEnumerable.GetEnumerator
y IEnumerable<T>.GetEnumerator
. Esto es lo que la implementación de interfaz explícita está destinado a resolver:
class X<T> : IEnumerable<T> {
List<T> _list = new List<T>();
public IEnumerator<T> GetEnumerator() {
return _list.GetEnumerator();
}
IEnumerator GetEnumerator() {
return GetEnumerator(); // invokes IEnumerable<T>.GetEnumerator
}
}
miembros que son implementaciones de interfaces explícitas son accesibles solamente a través de una instancia de la interfaz. Por lo tanto:
X<int> x = new X<int>();
var e1 = x.GetEnumerator(); // invokes IEnumerable<int>.GetEnumerator
// IEnumerable.GetEnumerator is not visible
IEnumerable y = x;
var e2 = y.GetEnumerator(); // invokes IEnumerable.GetEnumerator
Por lo tanto, en el código
X ob = new Y();
ob.add(1, 2); // X.add is visible through interface
Y y = new Y();
y.add(1, 2); // compile-time error, X.add is not visible
Ambos métodos no requieren modificadores pero cuando yo no uso la interfaz, como X.add() anterior, que necesitan hacer pública la implementación. ¿Por qué?
De acuerdo, no está claro exactamente lo que está preguntando aquí. Los modificadores de acceso no están permitidos para implementaciones de interfaz explícitas. Esto es de 13,4:
Se trata de un error en tiempo de compilación para una implementación explícita miembro de interfaz para incluir modificadores de acceso, y es un error en tiempo de compilación para incluir los modificadores abstract
, virtual
, override
o static
.
Si una implementación de interfaz no está marcada como una implementación de interfaz explícita, entonces debe tener el modificador de acceso public
. Esto es 13.4.4 (mapeo Interface):
mapeo de interfaz para una clase o estructura C
localiza una implementación para cada miembro de cada interfaz especificada en la lista de clase base de C
. La implementación de un miembro de interfaz particular I.M
, donde I
es la interfaz en la que se declara el miembro de M
, se determina mediante el examen de cada clase o struct S
, comenzando con C
y repitiendo para cada clase base sucesiva de C
, hasta que un partido se encuentra
Si S
contiene una declaración de un miembro de aplicación de interfaz explícita que coincide con I
y M
, entonces esta persona es la implementación de I.M
De lo contrario, si S
contiene una declaración de un miembro público no estático que coincide con M
, este miembro es la implementación de I.M
.
Un error de tiempo de compilación se produce si implementaciones no pueden ser localizados para todos los miembros de todas las interfaces especificadas en la lista de la clase base de C
.
Así que, en resumen, el compilador busca primero una implementación de interfaz explícita. Si no puede encontrar uno, busca un miembro público no estático, con la misma firma que el método M
que se está implementando. Si no puede encontrar uno, se produce un error en tiempo de compilación. Entonces las reglas son esto.Para implementar un miembro de interfaz I.M
:
Si implementa I.M
explícitamente a continuación, la sintaxis es
return-type I.M(parameter-list)
De lo contrario, la sintaxis es
public return-type M(parameter-list)
Por lo tanto, la
podemos implementar de forma explícita:
class Explicit : IAdd {
int IAdd.Add(int x, int y) { return x + y; }
}
o no:
class NotExplicit : IAdd {
public int Add(int x, int y) { return x + y; }
}
La diferencia es entonces que Explicit.Add
no es visible a menos casos de Explicit
se escriben como IAdd
:
IAdd explicitInterface = new Explicit();
explicitInterface.Add(2, 2);
Explicit explicit = new Explicit();
explicit.Add(2, 2); // compile-time error
mientras que
IAdd notExplicitInterface = new NotExplicit();
notExplicitInterface.Add(2, 2);
NotExplicit notExplicit = new NotExplicit();
notExplicit.Add(2, 2); // okay, NOT a compile-time error as above
ayuda eso?
posible duplicado de http://stackoverflow.com/questions/1652123/is-there-a-reason-you-can-not-define-the-access-modifier-on-a-method-or-in- an-int –