Why have class-level access modifiers instead of o

2019-01-22 14:19发布

问题:

While using C#, I recently realised that I can call a Foo object's private functions from Foo's static functions, and even from other Foo objects. After everything I have learned about access modifiers, this sounds very strange to me.

As far as I know, you make a function private when it does something that's part of some kind of internal process. Only the object itself knows when to use those functions, because other objects shouldn't/can't control the object's flow. Is there any reason why other objects of the same class should be excepted from this pretty straightforward rule?

As per request, an example:

public class AClass {
    private void doSomething() { /* Do something here */ }
    public void aFunction() {
        AClass f = new AClass();
        f.doSomething(); // I would have expected this line to cause an access error.
    }
}

回答1:

When you make a member private, it's private to other classes not the class itself.

It can be useful for instance if you have an Equals method which needs access to another instance's private members:

public class AClass
{
    private int privateMemberA;

    // This version of Equals has been simplified
    // for the purpose of exemplifying my point, it shouldn't be copied as is
    public override bool Equals(object obj)
    {
        var otherInstance = obj as AClass;
        if (otherInstance == null)
        {
            return null;
        }

        return otherInstance.privateMemberA == this.privateMemberA;
    }
}


回答2:

The private modifier enforces Encapsulation principle.

The idea is that 'outer world' should not make changes to AClass internal processes because AClass implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).

When instance of AClass accesses internals of other AClass instance - you can be sure that both instances always know the details of implementation of AClass. If the logic of internal to AClass processes is changed - all you have to do is change the code of AClass.

In some other languages, however, private works on instance level, but this is not true in C#.



回答3:

Private members are only accessibly from all other members within the scope of that class. It does not matter if this is done by multiple instances or one instance.

You are trying to restict members to be only called from this., so they are not allowed to be called from the outside world (seen from the point of view of the instance), but they are allowed to be called once you have entered the scope of your instance. This is simply not possible in C#.

Would be a nice feature though... :)



回答4:

The private (C# Reference) topic says:

The private keyword is a member access modifier. Private access is the least permissive access level. Private members are accessible only within the body of the class or the struct in which they are declared (...)

Even more:

Nested types in the same body can also access those private members.

So the following code will work perfectly.

class Foo
{
    private void PrivateMethod()
    {
    }
    class FooBaby
    {
        public static void MethodB()
        {
            Foo foo = new Foo();
            foo.PrivateMethod();
        }
    }
}

Concerning the question "why" classes have access modifiers and not the objects, it's one of the ways through which information is hidden in OOP (read more about Encapsulation (object-oriented programming).

I also recommend you to go through the chapters:

  • 10.5 Member access
  • 17.2.3 Access modifiers

of the Standard ECMA-334 C# Language Specification.



回答5:

private means that you can only access it from the class itself. Whether it is static or not makes no difference. Though it is no exception of this rule...

Christoph



回答6:

Well the reason you can access the private method is because you are inside the AClass

For example if you create a BClass and create an AClass inside you will not be able to access the private method

public class AClass
{
    private void doSomething() { /* Do something here */ }
    public void aFunction()
    {
        AClass f = new AClass();
        f.doSomething(); // we are inside AClass so we can access
    }
}

public class BClass
{
    private void doSomething() { /* Do something here */ }
    public void aFunction()
    {
        AClass f = new AClass();
        f.doSomething(); // Will not compile because we are outside AClass
    }
}

So basically its...

Public - If you can see the class, then you can see the method

Private - If you are part of the class, then you can see the method, otherwise not.