2013-05-20 13 views
7

Ich lese Buch "C# 4.0 in aller Kürze" von Joseph Albabari und Ben Albabari. Von dort finde ich ein Thema Einschränkungen für Zugriffsmodifikatoren. Seite 91, Thema "Einschränkungen für Zugriffsmodifikatoren".Inkonsistente Zugänglichkeit: Basisklasse ist weniger zugänglich als untergeordnete Klasse

Zitat aus dem Buch.

Der Compiler verhindert eine inkonsistente Verwendung von Zugriffsmodifikatoren. Für Beispiel eine Unterklasse selbst kann als eine Basisklasse weniger zugänglich sein, aber nicht mehr

So sagt dies, dass Basisklasse sollte als Unterklasse gleich oder mehr zugänglich sein. Wenn also die Basisklasse intern ist, sollte die Unterklasse entweder privat oder intern sein. Wenn die Basisklasse privat ist und die Unterklasse public ist, wird ein Kompilierzeitfehler generiert. Während ich dies in Visual Studio versuchte, fand ich ein seltsames Verhalten.

Versuch 1: Base ist privat und Subklasse ist privat (funktioniert, rechtes Verhalten) Dies funktioniert auch, wenn beide intern, öffentlich sind.

private class A { } 
private class B : A { }   // Works 

Versuchen 2: Basis privat und Unterklasse öffentlich oder intern (dies fehlschlägt, richtiges Verhalten)

private class A { } 
public class B : A { }   // Error 

3 Versuchen: Basis ist die interne und Unter ist öffentlich (Dies funktioniert, aber es ausfallen sollte. als Basis weniger zugänglich als Unterklasse ist

internal class A { } 
public class B : A { }   // Works, but why 

Jetzt ist meine Frage, warum Versuch 3 nicht versagt hat? Sub-Klasse ist öffentlich und zugänglicher als Basisklasse ist, die intern ist. Auch das Buch sagt thi s sollte fehlschlagen. Aber Visual Studio hat das erfolgreich kompiliert. Das sollte funktionieren oder nicht?

Edit:

habe ich ein neues Konsolenprojekt in VS. In Program.cs habe ich meinen Code hinzugefügt. Hier ist der vollständige Code der Datei Program.cs.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 

namespace ConsoleApplication 
{ 
    class Program 
    { 
     internal class A { } 
     public class B : A { }   // Error 

     static void Main() 
     { 
     } 
    } 
} 
+0

Technisch kann 'internal_ _can_ für die Verwendung außerhalb der Assembly über das Attribut [InternalsVisibleTo] (http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx) verfügbar gemacht werden Vielleicht ist das der Grund dafür. Ich werde sehen, ob ich einen bestimmten Eintrag in der C# Spezifikation finden kann. –

+0

Probieren Sie 3 Arbeiten für mich, dh. Fehler beim Kompilieren mit inkonsistentem Erreichbarkeitsfehler – amnezjak

+0

Ich dachte auch an das Attribut InternalsVisibleTo, aber was, wenn ich das nicht in meiner Assembly-Datei erwähne. Es muss einen anderen Grund dafür geben. –

Antwort

11

Sie Ihre verschachtelte Klassen innerhalb andere internal Klasse platzieren.

Zum Beispiel gegeben:

class Program 
{ 
    static void Main(string[] args) 
    { 
    } 

    internal class A { } 
    public class B : A { } 
} 

Es wird kompilieren, da der internal Modifikator der Verpackungs Klasse B strittiger das public Modifikator auf Klasse. Eher, Typ B 's Zugänglichkeit wird durch seine eingekapselte Klasse Program begrenzt - seine Zugänglichkeitsdomäne ist internal ebenso.

Wenn Sie aktualisieren, es zu sein:

class Program 
{ 
    static void Main(string[] args) 
    { 
    } 
} 

internal class A { } 
public class B : A { } 

Es wird die inkonsistente Sicht Compiler-Fehler werfen. Oder wenn Sie Program zu public statt internal neu definieren, wird es auch den Fehler werfen.In diesem Fall ist die Zugriffsdomäne B jetzt public und nicht mehr durch Programinternal Zugänglichkeitsdomäne beschränkt.


Von der C# Spezifikation 3.5.2 Accessibility Domains:

Die Zugriffsdomäne eines verschachtelten Element M in einem Typ T erklärt innerhalb eines Programms P wie folgt definiert ist (unter Hinweis darauf, dass M selbst kann möglicherweise sein ein Typ):

Wenn die deklarierte Zugänglichkeit von M öffentlich ist, ist die Zugriffsdomäne von M die Zugriffsdomäne von T.

Und die MSDN's description der Zugänglichkeit Domain:

Wenn das Mitglied innerhalb eines anderen Typs verschachtelt ist, seine Zugriffsdomäne wird sowohl von der Zugänglichkeit Ebene des Elements bestimmt und der Zugriffsdomäne der unmittelbar enthält Art.

Wenn die Umschlingungstyp Programinternal ist, dann ist die verschachtelte Art B sein public seine Zugänglichkeit haben Program anzupassen, so dass es als internal behandelt wird und kein Compiler-Fehler ausgelöst wird.

+0

Ja, es ist jetzt fehlgeschlagen. Ich stelle sie außerhalb der Programmklasse. Danke für die Hilfe. –

+0

@FaisalHafeez Ich glaube, ich habe den Eintrag in der C# -Spezifikation gefunden, der dieses Verhalten beschreibt. Gute Frage! –

+0

Nette Verwendung der Spezifikation hier. –

Verwandte Themen