Freigeben über


Einschränken des Accessorzugriffs (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. In der Regel wird die Zugänglichkeit der set-Zugriffsmethode eingeschränkt, während die get-Zugriffsmethode ö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.

Hinweis

In den Beispielen in diesem Artikel werden keine automatisch implementierten Eigenschaften verwendet. Automatisch implementierte Eigenschaften bieten eine präzise Syntax zum Deklarieren von Eigenschaften, wenn kein benutzerdefiniertes Sicherungsfeld erforderlich ist.

Einschränkungen für Zugriffsmodifizierer für Accessoren

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

  • Zugriffsmodifizierer können nicht für eine Schnittstelle oder eine explizite interface-Memberimplementierung 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 der Zugriff 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 Schnittstellen

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.

Wird kein Zugriffsmodifizierer für die Zugriffsmethode verwendet, wird die Zugriffsdomäne der Zugriffsmethode 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 private oder protected, für die set-Zugriffsmethode der Eigenschaft Name in DerivedClass den Zugriff auf die Zugriffsmethode in der abgeleiteten Klasse verhindert. Bei einer Zuweisung oder beim Zugriff auf Basisklasseneigenschaft mit demselben Namen (sofern zugänglich) 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