Asymmetrischer Accessorzugriff (C#-Programmierhandbuch)

Aktualisiert: November 2007

Die Abschnitte get und set einer Eigenschaft oder eines Indexers werden als Accessoren bezeichnet. Diese Accessoren weisen standardmäßig dieselbe Sichtbarkeits- bzw. Zugriffsebene auf, und zwar diejenige der Eigenschaft oder des Indexers, der bzw. dem sie angehören. Weitere Informationen finden Sie unter Zugriffsebenen. In bestimmten Fällen ist es jedoch nützlich, den Zugriff auf einen der beiden Accessoren einzuschränken. Normalerweise wird der Zugriff auf den set-Accessor eingeschränkt, während auf den get-Accessor weiterhin öffentlich zugegriffen werden kann. Beispiel:

private string name = "Hello";

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

In diesem Beispiel definiert die Eigenschaft Name einen set-Accessor und einen get-Accessor. Dem get-Accessor wird die Zugriffsebene der Eigenschaft selbst zugewiesen, public in diesem Fall, während der set-Accessor explizit eingeschränkt wird, indem der protected-Zugriffsmodifizierer auf den Accessor selbst angewendet wird.

Einschränkungen für Zugriffsmodifizierer bei Accessoren

Die Anwendung von Accessormodifizierern auf Eigenschaften oder Indexer unterliegt den folgenden Bedingungen:

  • Sie können Accessormodifizierer nicht für eine Schnittstelle oder eine explizite Implementierung eines Schnittstellenmembers verwenden.

  • Sie können nur Accessormodifizierer verwenden, wenn die Eigenschaft oder der Indexer sowohl über einen set-Accessor als auch über einen get-Accessor verfügt. In diesem Fall ist der Modifizierer nur auf einem der beiden Accessoren erlaubt.

  • Wenn die Eigenschaft oder der Indexer einen override-Modifizierer besitzt, muss der Accessormodifizierer dem Accessor des überschriebenen Accessors (falls vorhanden) entsprechen.

  • Die Zugriffsebene für den Accessor muss restriktiver sein als die Zugriffsebene für die Eigenschaft oder den Indexer.

Zugriffsmodifizierer auf überschreibenden Accessoren

Wenn Sie eine Eigenschaft oder einen Indexer überschreiben, müssen die überschriebenen Accessoren für den überschreibenden Code zugänglich sein. Außerdem muss die Zugriffsebene sowohl von Eigenschaft/Indexer als auch der Accessoren mit den überschriebenen Entsprechungen von Eigenschaft/Indexer und der Accessoren übereinstimmen. 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

Wenn Sie einen Accessor verwenden, um eine Schnittstelle zu implementieren, ist es möglich, dass der Accessor keinen Zugriffsmodifizierer hat. Wenn Sie die Schnittstelle mit einem Accessor implementieren, z. B. mit get, kann der andere Accessor einen Zugriffsmodifizierer haben. 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 { }
    }
}

Accessorzugriffsdomäne

Wenn Sie auf dem Accessor einen Zugriffsmodifizierer verwenden, wird die Zugriffsdomäne des Accessors von diesem Modifizierer bestimmt.

Wenn Sie auf dem Accessor keinen Zugriffsmodifizierer verwendet haben, wird die Zugriffsdomäne des Accessors von der Zugriffsebene der Eigenschaft bzw. des Indexers bestimmt.

Beispiel

Das folgende Beispiel enthält drei Klassen: BaseClass, DerivedClass und MainClass. Es gibt zwei Eigenschaften auf der BaseClass, Name und Id auf beiden Klassen. Im Beispiel wird veranschaulicht, wie die Id-Eigenschaft für DerivedClass durch die Id-Eigenschaft für BaseClass ausgeblendet wird, wenn ein restriktiver Zugriffsmodifizierer wie protected oder private verwendet wird. Wenn Sie dieser Eigenschaft Werte zuweisen, wird daher stattdessen die Eigenschaft auf der BaseClass-Klasse aufgerufen. Indem Sie den Zugriffsmodifizierer durch public ersetzen, kann auf die Eigenschaft zugegriffen werden.

Das Beispiel zeigt auch, dass ein restriktiver Zugriffsmodifizierer (z. B. private oder protected) auf dem set-Accessor der Name-Eigenschaft in DerivedClass den Zugriff auf den Accessor verhindert und einen Fehler generiert, sobald Sie darauf verweisen.

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 Sie beim Ersetzen der Deklaration new private string Id durch new public string Id die folgende Ausgabe erhalten:

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

Name and ID in the derived class: John, John123

Siehe auch

Konzepte

C#-Programmierhandbuch

Referenz

Eigenschaften (C#-Programmierhandbuch)

Indexer (C#-Programmierhandbuch)

Zugriffsmodifizierer (C#-Programmierhandbuch)