Begränsa hjälpmedel för accessor (C#-programmeringsguide)

Hämta och ange delar av en egenskap eller indexerare kallas accessorer. Som standard har dessa användare samma synlighets- eller åtkomstnivå för den egenskap eller indexerare som de tillhör. Mer information finns i hjälpmedelsnivåer. Ibland kan det dock vara bra att begränsa åtkomsten till någon av dessa åtkomster. Vanligtvis begränsar du tillgängligheten set för accessorn, samtidigt som get du håller åtkomstgivaren offentligt tillgänglig. Till exempel:

private string _name = "Hello";

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

I det här exemplet definierar en egenskap med namnet Name a get och set accessor. Accessorn get får tillgänglighetsnivån för själva egenskapen, public i det här fallet, medan accessorn uttryckligen set begränsas genom att använda den skyddade åtkomstmodifieraren på själva åtkomstgivaren.

Kommentar

Exemplen i den här artikeln använder inte automatiskt implementerade egenskaper. Auto-implementerade egenskaper ger en koncis syntax för att deklarera egenskaper när ett anpassat säkerhetskopieringsfält inte krävs.

Begränsningar för åtkomstmodifierare för accessorer

Följande villkor gäller för att använda åtkomstmodifierarna för egenskaper eller indexerare:

  • Du kan inte använda åtkomstmodifierare i ett gränssnitt eller en explicit implementering av gränssnittsmedlemmar .
  • Du kan endast använda åtkomstmodifierare om egenskapen eller indexeraren har både set och get accessorer. I det här fallet tillåts modifieraren endast på en av de två åtkomstgivarna.
  • Om egenskapen eller indexeraren har en åsidosättningsmodifierare måste accessormodifieraren matcha accessorn för den åsidosättningsmodifierare som finns.
  • Tillgänglighetsnivån för accessorn måste vara mer restriktiv än tillgänglighetsnivån för själva egenskapen eller indexeraren.

Åtkomst till modifierare på överordnade åtkomstorer

När du åsidosätter en egenskap eller indexerare måste de åsidosatta åtkomsterna vara tillgängliga för den övergripande koden. Dessutom måste tillgängligheten för både egenskapen/indexeraren och dess accessorer matcha motsvarande åsidosatta egenskap/indexerare och dess accessorer. Till exempel:

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; }
    }
}

Implementera gränssnitt

När du använder en accessor för att implementera ett gränssnitt kanske inte åtkomstmodifieraren har någon åtkomstmodifierare. Men om du implementerar gränssnittet med hjälp av en accessor, till exempel get, kan den andra åtkomstmodifieraren ha en åtkomstmodifierare, som i följande exempel:

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 { }
    }
}

Tillgänglighetsdomän för accessor

Om du använder en åtkomstmodifierare på accessorn bestäms tillgänglighetsdomänen för accessorn av den här modifieraren.

Om du inte använde en åtkomstmodifierare på accessorn bestäms åtkomstdomänen för åtkomstgivaren av tillgänglighetsnivån för egenskapen eller indexeraren.

Exempel

Följande exempel innehåller tre klasser, BaseClass, DerivedClassoch MainClass. Det finns två egenskaper för BaseClass, Name och Id på båda klasserna. Exemplet visar hur egenskapen IdDerivedClass kan döljas av egenskapen IdBaseClass när du använder en restriktiv åtkomstmodifierare, till exempel skyddad eller privat. När du tilldelar värden till den här egenskapen anropas därför egenskapen för BaseClass klassen i stället. Om du ersätter åtkomstmodifieraren med offentlig blir egenskapen tillgänglig.

Exemplet visar också att en restriktiv åtkomstmodifierare, till exempel private eller protected, på set egenskapens Name accessor i DerivedClass förhindrar åtkomst till accessorn i den härledda klassen. Det genererar ett fel när du tilldelar den, eller får åtkomst till basklassegenskapen med samma namn, om den är tillgänglig.

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
*/

Kommentarer

Observera att om du ersätter deklarationen new private string Id med new public string Idfår du utdata:

Name and ID in the base class: Name-BaseClass, ID-BaseClass Name and ID in the derived class: John, John123

Se även