-1

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

Siegfried.V
  • 1,508
  • 1
  • 16
  • 34
  • 1
    First of all, these are not "parameters". `id` is a "field", and `ID` is a "property". – Klaus Gütter Oct 06 '19 at 13:51
  • 1
    @KlausGütter ok, excuse me for not correct language, would ask what is difference between `field` and `property`, but will look further about it, thanks. – Siegfried.V Oct 06 '19 at 13:52
  • 3
    private members of a class are not accessible anywhere except the class itself. They are not accessible even in inherited class. You need to have protected members if you wish them to be accessible in inherited classes. – Chetan Oct 06 '19 at 13:52
  • "field" is what is actually store in the object instance. "property" is a nice syntax for a pair of get-set accessors. – Klaus Gütter Oct 06 '19 at 13:54
  • If you have ID property declared as public why you don't want to access it from the inherited class? Why you specifically want to use `id` field in the inherited class? Declaring new private id will not help – Chetan Oct 06 '19 at 13:54
  • @ChetanRanpariya so just to be sure I understood correctly, I just need to replace `private` by `protected` for all fields? And could you explain why code is debugging without any error if I don't do it, thanks. – Siegfried.V Oct 06 '19 at 13:54
  • @ChetanRanpariya it is only for obfuscation, I noticed that my obfuscator (Eazfuscator), obfuscates all private (fields), but no public ones. So I try as much as possible to use private instead of public everywhere. – Siegfried.V Oct 06 '19 at 13:56
  • 2
    You need to make only those members `protected` which you want to use in inherited classes. As I said you can access the public member of the base class. So when public property is used in inherited class, whatever code written in the property will be executed. Its the same as you are accessing property from outside the class. – Chetan Oct 06 '19 at 13:58
  • @ChetanRanpariya yes I understood, until now I did so (didn't even declare the private fields except when I needed to make some binding), but it is only for protection reason, as wroten I noticed that if I use fields, they are obfuscated, so no reversing is possible (at first sight), but if I use public properties, no obfuscation is done. – Siegfried.V Oct 06 '19 at 14:04

3 Answers3

2

Here is a short and reduced description of what access modifiers do:

  • Public : fields (variables) and properties (variables encapsulation) and methods (functions and procedures) are visible and accessible by the class itslef, by its childs and by any other external classes.

  • Private : members (fields, properties and methods) are visible and accessible only by the class, not by its childs nor by any external class.

  • Protected : members are visible and accessible by the class and by its childs, but not by others classes.

  • Internal : members are visible and accessible by the class and by its childs and by any class that is in the same assembly (.exe and .dll), but not by a class from another assembly.

So you should set id to protected in the parent class to use it in the childs.

But here is the rule:

  • If childs classes can modify id you should set as a protected field, and offer a public property (get) if available for external items.

  • If childs classes are not allowed to modify it you should set it private and offer :

    • A propected property with only a getter if external items can't access it.

    • A public property with only a getter if external items can access it.

Don't repeat a member with the same name else it will hide the parent and can cause polymorphism problems, else you know what you do.

You can read these tutorials to more understand access modifier keywords:

C# Access Modifiers

Access Modifiers (C# Reference)

Here are some readings:

C# Tutorial Level 0
C# Tutorial Level 1
C# Tutorial Level 2
C# Tutorial Level 3

C# Snippets @ Techi.io

Beginning Visual C# 2008 Programming

2

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:

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • I believed that it was needed for security reasons? and as explained, because my obfuscator obfuscates all private fiels everytime I use them, and not public ones. `this.ID=this.PublicParameter` is not obfuscated, but `this.id=this.privateParameter` will be obfuscated, so if I try to reverse the code I just see `kgkjkghllk=khgjgk`, that's the main reason why I try to all "privatise" in all of my libraries – Siegfried.V Oct 06 '19 at 14:26
  • 1
    Don't write bad code so an obfuscator can make it even worse. If you write code people find worth deobfuscating, they will do so anyway. If not, you're just wasting your time. – CodeCaster Oct 06 '19 at 14:28
  • well I may have asked before then... just spent 3 days in modifying all my code just for that... Just now I began to do i on children classes – Siegfried.V Oct 06 '19 at 14:37
0

The MyChildClass class which inherits from the MyFatherClass can not access the id field because it's private. To make it accessible, you will need to change the field's access modifier to either:

protected :

////////////////////////////////////
// Dll1.dll
////////////////////////////////////

namespace Dll1
{
    public class Base
    {
        //The field we are attempting to access
        protected int a;
    }

    public sealed class Main : Base
    {
        public void DoSomething()
        {
            //Can be done sins Main inherits from Base
            base.a = 100;
        }
    }

    public class Invader
    {
        public int GetA()
        {
            var main = new Main();

            main.DoSomething();

            // can not be done sins the field is only accessible by those that inherit from Base
            return main.a;
        } 
    }
}

////////////////////////////////////
// Dll2.dll
////////////////////////////////////

namespace Dll2
{
    public class ADll2Class : Dll1.Base
    {
        public int GetA()
        {
            //Can be done because ADll2Class inherits from Dll1's Base class
            return base.a;
        }
    }

}

private protected :

Same as protected but, in the example above, Dll2's class, ADll2Class, will not be able to access the a field because it would be privately protected, in other words only classes from the same dll as Base which inherit from Base will be able to access a.

or you can set it to

internal :

If the a field in the example above was internal, then, same as private protected, Dll2's class wont be able to access it but, the Invader class in Dll1 will be able to access it sins it's part of the same dll as Base.

Note that, sins you mentioned obfuscation, try as hard as you will, the id field can still be accessed by others in an obfuscated state with the help of reflection, especially sins you provide a public property ID, might as well set everything in your project to internal.

Vincent Bree
  • 425
  • 4
  • 10