greenonion
greenonion

Reputation: 105

Accessing inherited private base class member...through derived class object...created in base class member

I can't wrap my head around why m() in class a can access x and y through the b class and b class object if x and y are private. I know that when b inherits from a, b receives private members from a even though they can't be used by b. But what is strange to me is that b members can't use x and y, and classes other than a can't get at the variables through b class and b class object, yet m() can access x and y through the b class and b class object.

Can someone explain this to me using a general rule that I missed or maybe an explanation about how the compiler does this 'giving' of base members to derived classes?

class a
{
    private int x;
    private static int y;

    static void m()
    {
        b bobj = new b();
        int mm = bobj.x;
        int rr = b.y;


    }

    void n()
    {
        b bobj = new b();
        int mm = bobj.x;
        int rr = b.y;
    }
}

class b : a
{
    private int u;
    private static int v;

    static void o()
    {

    }

    void p()
    {

    }
}

Upvotes: 0

Views: 3267

Answers (2)

Jirka Hanika
Jirka Hanika

Reputation: 13529

This is a rule inherited from the C++ language.

private and protected operate on classes, not objects. Therefore, for example, if you have a Bank object, its members can access any other Bank's private data although it may seem counterintuitive or dangerous.

Because C++ extensively used pointer arithmetic and unlimited typecasts, there was no way to reliably protect data inside a process before any code executing in the same process.

If you, however, only need object level protection from accidental access, this can be helped by defining an interface and only passing interfaces between banks. While a Bank object still can do the following:

void TransferMoneyFrom(IBank otherBank, decimal theirAccountNumber,
                        decimal receivingAccountNumber, int amount)
{
    ((Bank)otherBank).PrivateProperty = whatever;
}

...it is less likely to happen unintentionally because explicit type casting or use of reflection are needed.

(Note that C# typically makes it easier to intentionally access a private member of some other class whose source code you do not have (by name, using reflection). If this is perceived as a disadvantage by the vendor of that type, they can use an obfuscator to make this more difficult. This still does not protect the obfuscated objects against other instances of itself in any way.)

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500135

I can't wrap my head around why m() in class a can access x and y through the b class and b class object if x and y are private

Code within a class declaration can access any private members declared by that class - it's as simple as that. So code within a can't access private variables declared in b, but it can access private variables declared in a via an instance of a which also happens to be an instance of b.

Note that this line:

int rr = b.y;

is effectively converted to

int rr = a.y;

y is only declared by a - if it were really declared by b, it wouldn't be accessible.

See section 3.5 of the C# 4 language specification for more details.

Upvotes: 3

Related Questions