Come funziona il modificatore di accesso protetto C # quando applicato a una variabile membro

1

Ho 2 classi, base e classe figlio. La classe base ha una variabile int protetta. La mia comprensione è che a qualsiasi membro protetto di una classe è possibile accedere solo in una classe figlia, non è possibile accedervi, ad esempio creando un'istanza di una classe e accedendo al membro protetto. Come funziona allora?

  class BaseClass
        {
            protected int x = 0;

            private static void Funny(BaseClass c, ChildClass d)
            {
                d.x = 9; // How can we access x here? 
                c.x = 0; // How can we access x here?
            }
        }

        class ChildClass: BaseClass
        {
            public void MyFunc()
            {
                x = 0; // This should be OK, because x is a protected member of 
            }

            private static void Funny(BaseClass c,ChildClass d)
            {

                d.x = 9;
                c.x=0;// This is giving compile time error? According to me even above line should give compile time error


            }
        }
    
posta Charu 04.06.2015 - 10:43
fonte

2 risposte

2

In C #, l'ambito dei modificatori di accesso è la classe , non l'istanza . Ciò significa che è possibile accedere a un membro privato all'interno della classe in qualsiasi istanza.

public class Price
{
    private int amount;

    private static void CheckAmountOf(Price price)
    {
        // The following line is possible, even if 'amount' is private and we are accessing an
        // instance of the object which was passed by a parameter.
        if (price.amount < 0)
        {
            throw new InvalidValueException("The price cannot be negative.");
        }
    }
}

Questo, a proposito, rende possibile (e facile) per override uguale a . Altrimenti, verrai limitato alle sole proprietà pubbliche, il che potrebbe non essere esattamente quello che desideri.

class Price
{
    private int amount;

    public override bool Equals(object obj)
    {
        ...
        var price = obj as Price;
        ...
        // The next line is valid, even if 'amount' is private and even if the initial argument
        // was of type 'object'. This way, you don't need to have a corresponding 'Amount'
        // property with a public getter.
        return this.amount == price.amount;
    }
}
    
risposta data 04.06.2015 - 10:55
fonte
1

La risposta di MainMa spiega perché la maggior parte degli accessi funziona. Tuttavia, per capire perché l'ultimo non funziona, vediamo cosa potremmo fare se fosse consentito:

class SiblingClass: BaseClass
{
}

    //...And then, inside some other code:
    var sibling = new SiblingClass();
    var child = new ChildClass();
    ChildClass.Funny(sibling, child);

(Questo richiede anche che ChildClass.Funny venga reso pubblico)

Tutto ciò sarebbe ereditato da BaseClass in modo che potesse essere passato per un parametro di tipo BaseClass . Ma ora ChildClass può accedere a un membro su SiblingClass . Non è quello che ci aspettiamo dalla parola chiave protected - ci aspettiamo che dia accesso solo alle cose che eredita dal suo genitore, non a tutte altre classi che ereditano anche dal suo genitore.

Quindi, per evitare che questo accesso inaspettato accada, è reso illegale.

    
risposta data 04.06.2015 - 14:45
fonte

Leggi altre domande sui tag