Search code examples
c#obfuscationprivateencapsulationprotected

How to choose between private and protected access modifier to encapsulate members between base and childs classes?


I am trying on a project to use private values in my internal functions. In past I used only public ones, but I noticed that obfuscation is working much better when using as much as possible private parameters.

My question is regarding Parent/Child classes.

In my main class I define all the parameters as following :

public class MyFatherClass
{
    private long id = -1;
    public long ID { get { return this.id; } set { this.id = value; } }    
    ...
}

So in all internal functions I access to my private value instead of the public one.

Then in my daughter class I just add parameters specific to the child class.

public class MyChildClass : MyFatherClass
{
    private long anotherParameter = -1;
    public long AnotherParameter { get { return this.anotherParameter; } set { this.anotherParameter = value; } }    
    ...
}

Just, I see that in my Parent class, I can access to id and ID without problem, but from daughter classes I can only access ID(as id is private).

If I understood correct, I would need to replace all private by protected in my parent lass, so it would solve the problem? What I don't understand is the code is working even if I leave it so. Why don't I have an error message, when I set ID value in daughter class, the sentence this.id=value is executed, but how can can I access to it from my child class if it is private?

I am now hesitating, may I just add a private id in each child class, or may I set id to protected in my parent class?

Thanks for your explanations.

Edit, just adding a screenshot of my reversed code after obfuscation, so you could understand difference on how are obfuscated private/public methods/fields

enter image description here


Solution

  • Why don't I have an error message, when I set ID value in daughter class, the sentence this.id=value is executed, but how can can I access to it from my child class if it is private?

    When you call a public method on a class, that method can access private members of that class:

    public class Foo
    {
        public void Bar()
        {
            Baz();
        }
    
        private void Baz()
        {
            // private method called by public method
        }
    }   
    
    var foo = new Foo();
    foo.Bar();
    

    This compiles just fine. Your setter is the same: it's public, so callable from everywhere, even if it accesses private members.

    As for making your field (private long id = -1;) protected: yes, that will mean you can access it in derived classes. But whether you want to is another question.

    You have declared a public property for a reason. Perhaps you want to do some validation in its setter or getter. If not, if you're just using a property to access a private field, you could just ditch the entire private field and use an auto-implemented property:

    public long ID { get; set; } = -1;
    

    Then you can access the property everywhere, from within itself, from derived classes and from code using this class.

    See also: