Eine Schnittstelle ist ein Vertrag. Es sagt: "Ich kann diese Dinge tun." Was ist der Sinn von jemandem, der Ihnen eine Instanz von IInterface
übergibt, in der Sie einige der Methoden in diesem Vertrag nicht verwenden können, weil sie als nicht öffentlich markiert wurden?
Dies ist der Grund für die Gestaltung der Sprache auf diese Weise. Die Spezifikation hierfür ist in §13.2 der Sprachspezifikation:
Alle Schnittstellenmitglieder haben implizit öffentlichen Zugriff. Es ist ein Kompilierungsfehler für Interface-Member-Deklarationen, die alle Modifikatoren enthalten. Insbesondere können Schnittstellen Mitglieder nicht mit den Modifikatoren abstract
, public
, protected
, internal
, private,
virtual
, override
oder static
deklariert werden.
Wie für Ihren Code, das ist ein Beispiel für explicit interface implementation. Es ist am nützlichsten, wenn eine Klasse oder Struktur zwei Schnittstellen mit jeweils einem Element mit der gleichen Signatur implementiert. Zum Beispiel definieren sowohl IEnumerable
als auch IEnumerable<T>
eine Methode GetEnumerator
, die keine Parameter akzeptiert.
public interface IEnumerable {
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable {
IEnumerator<T> GetEnumerator();
}
Beachten Sie, dass durch die oben genannten Definitionen, die jede Klasse IEnumerable<T>
implementiert auch IEnumerable
implementieren müssen. Beachten Sie, dass der Rückgabetyp nicht Teil der Signatur ist und somit ein Konflikt mit IEnumerable.GetEnumerator
und IEnumerable<T>.GetEnumerator
vorliegt. Dies ist, was explizite Schnittstellenimplementierung ist zu lösen gemeint:
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
}
}
Mitglieder, die expliziten Interface-Implementierungen sind nur sichtbar durch eine Instanz der Schnittstelle. Also:
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
So in Ihrem Code
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
Beide Methoden erfordern keine Modifikatoren, aber wenn ich nicht Schnittstelle verwenden, wie X.add() oben, muss ich Machen Sie die Implementierung öffentlich. Warum?
Okay, es ist nicht klar, was genau Sie hier fragen. Zugriffsmodifizierer sind für explizite Schnittstellenimplementierungen nicht zulässig. Das ist 13,4:
Es ist ein Fehler bei der Kompilierung für eine explizite Schnittstellenmemberimplementierung Zugriffsmodifikatoren aufzunehmen, und es ist ein Fehler Compile-Zeit die Modifikatoren abstract
, virtual
, override
, einschließen oder static
.
Wenn eine Interface-Implementierung nicht als eine explizite Schnittstellenimplementierung gekennzeichnet ist, dann muss es den Zugriffsmodifikator haben public
. Dies ist 13.4.4 (Interface mapping):
Interface-Mapping für eine Klasse oder struct C
für jedes Mitglied jeder Schnittstelle eine Implementierung findet in der Basisklasse Liste von C
angegeben. Die Umsetzung eines bestimmten Schnittstellenelement I.M
, wo I
ist die Schnittstelle in der das Element M
deklariert ist, wird durch Prüfen jede Klasse oder struct S
, beginnend für jede aufeinanderfolgende Basisklasse von C
mit C
und Wiederholen bestimmt, bis eine Übereinstimmung befindet
Wenn S
enthält eine Erklärung einer expliziten Interface-Member-Implementierung, die I
und M
übereinstimmt, dann ist dieses Mitglied die Umsetzung von I.M
Andernfalls, wenn S
eine Deklaration eines nicht statischen öffentlichen Mitglieds enthält, das mit M
übereinstimmt, ist dieses Element die Implementierung von I.M
.
Ein Fehler bei der Kompilierung tritt auf, wenn Implementierungen kann nicht für alle Mitglieder aller Schnittstellen in der Basisklasse Liste der C
angegeben befindet.
Kurz gesagt, der Compiler sucht zuerst nach einer expliziten Schnittstellenimplementierung. Wenn es keinen finden kann, sucht es nach einem nicht statischen, öffentlichen Mitglied mit der gleichen Signatur wie die Methode M
, die implementiert wird. Wenn es keinen finden kann, tritt ein Kompilierungsfehler auf. Also sind die Regeln das.Um eine Schnittstelle zu implementieren Mitglied I.M
:
Wenn Sie I.M
implementieren explizit dann die Syntax
return-type I.M(parameter-list)
Ansonsten ist die Syntax
public return-type M(parameter-list)
So mit
Wir implementieren ausdrücklich:
class Explicit : IAdd {
int IAdd.Add(int x, int y) { return x + y; }
}
oder nicht:
class NotExplicit : IAdd {
public int Add(int x, int y) { return x + y; }
}
Der Unterschied ist dann, dass Explicit.Add
nicht sichtbar ist, wenn Instanzen von Explicit
als IAdd
eingegeben werden :
IAdd explicitInterface = new Explicit();
explicitInterface.Add(2, 2);
Explicit explicit = new Explicit();
explicit.Add(2, 2); // compile-time error
während
IAdd notExplicitInterface = new NotExplicit();
notExplicitInterface.Add(2, 2);
NotExplicit notExplicit = new NotExplicit();
notExplicit.Add(2, 2); // okay, NOT a compile-time error as above
Does diese Hilfe?
möglich Duplikat von http://Stackoverflow.com/questions/1652123/is-there-a-reason-you-cann-not-define-the-access-modifier-on-a-method-or-in-in- an-int –