Einschränken des Zugriffsmethodenzugriffs (C#-Programmierhandbuch)

Die Get- und Set-Teile einer Eigenschaft oder eines Indexers werden Zugriffsmethoden oder Accessoren genannt. Standardmäßig weisen diese Zugriffsmethoden dieselbe Sichtbarkeit oder Zugriffsebene auf: nämlich die der Eigenschaft oder des Indexers, zu dem sie gehören. Weitere Informationen finden Sie unter Zugriffsebenen. Allerdings ist es manchmal sinnvoll, den Zugriff auf eine der beiden Zugriffsmethoden einzuschränken. Dies bedeutet in der Regel, dass der Zugriff auf den set-Accessor eingeschränkt wird, während der get-Accessor öffentlich zugänglich bleibt. Zum Beispiel:

private string name = "Hello";

public string Name
{
    get
    {
        return name;
    }
    protected set
    {
        name = value;
    }
}

In diesem Beispiel definiert die Eigenschaft Name einen get- und einen set-Accessor. Der get-Accessor erhält die Zugriffsebene der Eigenschaft selbst, in diesem Fall public. Der set-Accessor wird jedoch explizit durch Anwenden des Protected-Zugriffsmodifizierers auf den Accessor selbst eingeschränkt.

Einschränkungen für Zugriffsmodifizierer für Accessoren

Bei der Verwendung von Accessormodifizierern auf Eigenschaften oder Indexer muss Folgendes beachtet werden:

  • Accessormodifizierer können nicht bei einer Schnittstelle oder einer expliziten Schnittstellen-Member-Implementierung verwendet werden.

  • Accessormodifizierer können nur verwendet werden, wenn die Eigenschaft oder der Indexer sowohl einen set- als auch einen get-Accessor besitzt. In diesem Fall ist der Modifizierer nur für einen der beiden Accessoren zulässig.

  • Besitzt die Eigenschaft oder der Indexer einen Override-Modifizierer, muss der Accessormodifizierer mit dem eventuell vorhandenen Accessor des überschriebenen Accessors übereinstimmen.

  • Die Zugriffsebene des Accessors muss restriktiver sein als die Zugriffsebene der Eigenschaft oder des Indexers selbst.

Zugriffsmodifizierer für Override-Accessoren

Beim Überschreiben einer Eigenschaft oder eines Indexers müssen die überschriebenen Accessoren für den überschreibenden Code zugänglich sein. Außerdem müssen die Zugriffsebenen der Eigenschaft/des Indexers als auch der Accessoren mit der entsprechenden überschriebenen Eigenschaft/dem Indexer und den Accessoren übereinstimmen. Zum Beispiel:

public class Parent
{
    public virtual int TestProperty
    {
        // Notice the accessor accessibility level.
        protected set { }

        // No access modifier is used here.
        get { return 0; }
    }
}
public class Kid : Parent
{
    public override int TestProperty
    {
        // Use the same accessibility level as in the overridden accessor.
        protected set { }

        // Cannot use access modifier here.
        get { return 0; }
    }
}

Implementieren von Schnittsellen

Bei der Verwendung eines Accessors zur Implementierung einer Schnittstelle darf der Accessor keinen Zugriffsmodifizierer besitzen. Wird jedoch zur Implementierung der Schnittstelle nur ein Accessor verwendet, z.B. get, kann der andere Accessor einen Zugriffsmodifizierer besitzen. Hier ein Beispiel:

public interface ISomeInterface
{
    int TestProperty
    {
        // No access modifier allowed here
        // because this is an interface.
        get;
    }
}

public class TestClass : ISomeInterface
{
    public int TestProperty
    {
        // Cannot use access modifier here because
        // this is an interface implementation.
        get { return 10; }

        // Interface property does not have set accessor,
        // so access modifier is allowed.
        protected set { }
    }
}

Zugriffsdomäne des Accessors

Bei Verwendung eines Zugriffsmodifizierers für den Accessor wird die Zugriffsdomäne des Accessors durch diesen Modifizierer bestimmt.

Andernfalls wird die Zugriffsdomäne des Accessors durch die Zugriffsebene der Eigenschaft oder des Indexers bestimmt.

Beispiel

Das folgende Beispiel enthält drei Klassen: BaseClass, DerivedClass und MainClass. Für BaseClass gibt es zwei Eigenschaften, Name und Id für beide Klassen. Das Beispiel veranschaulicht, wie die Eigenschaft Id in DerivedClass durch die Eigenschaft Id in BaseClass ausgeblendet werden kann, wenn ein restriktiver Zugriffsmodifizierer, wie z.B. protected oder private, verwendet wird. Daher wird beim Zuweisen von Werten zu dieser Eigenschaft stattdessen die Eigenschaft für die Klasse BaseClass aufgerufen. Wird der Zugriffsmodifizierer durch public ersetzt, kann auf die Eigenschaft zugegriffen werden.

Das Beispiel zeigt auch, dass die Verwendung eines restriktiven Zugriffsmodifizierers, wie z.B. private oder protected, auf den set-Accessor der Eigenschaft Name in DerivedClass den Zugriff auf den Accessor verhindert. Mit dem Zuweisen zu dem Accessor wird ein Fehler generiert.

public class BaseClass
{
    private string name = "Name-BaseClass";
    private string id = "ID-BaseClass";

    public string Name
    {
        get { return name; }
        set { }
    }

    public string Id
    {
        get { return id; }
        set { }
    }
}

public class DerivedClass : BaseClass
{
    private string name = "Name-DerivedClass";
    private string id = "ID-DerivedClass";

    new public string Name
    {
        get
        {
            return name;
        }

        // Using "protected" would make the set accessor not accessible. 
        set
        {
            name = value;
        }
    }

    // Using private on the following property hides it in the Main Class.
    // Any assignment to the property will use Id in BaseClass.
    new private string Id
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
        }
    }
}

class MainClass
{
    static void Main()
    {
        BaseClass b1 = new BaseClass();
        DerivedClass d1 = new DerivedClass();

        b1.Name = "Mary";
        d1.Name = "John";

        b1.Id = "Mary123";
        d1.Id = "John123";  // The BaseClass.Id property is called.

        System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);
        System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
/* Output:
    Base: Name-BaseClass, ID-BaseClass
    Derived: John, ID-BaseClass
*/

Kommentare

Beachten Sie, dass beim Ersetzen der Deklaration new private string Id durch new public string Id Folgendes ausgegeben wird:

Name and ID in the base class: Name-BaseClass, ID-BaseClass

Name and ID in the derived class: John, John123

Siehe auch

C#-Programmierhandbuch
Eigenschaften
Indexer
Zugriffsmodifizierer