Why can I access to the Private properties when using constructor parameters inside the same class

Viewed 646

I have a working sample code, and I can not explain why this is working like this.

Take this class for example.

 public class TestClass
{
    private int _testValue;


    public void TestMethod()
    {
        var t = new TestClass() {_testValue = 42}; // Why is that working?
    }
}

Why is this allowed? I would have expected having the behavior as this:

static void Main(string[] args)
    {

        new TestClass() { _testValue = 23 }; // Does not compile and I am happy with that.

        // The code provided will print ‘Hello World’ to the console.
        // Press Ctrl+F5 (or go to Debug > Start Without Debugging) to run your app.
        Console.WriteLine("Hello World!");
        Console.ReadKey();

        // Go to http://aka.ms/dotnet-get-started-console to continue learning how to build a console app! 
    }

Edit: Tank you for your comments, but I know what private keyword mean, the question is, why Can I have access to the private properties when I am using a parameter constructor when I am inside the same object. Place a debugger, you will see that the TestClass this._testValue is not the same as the t._testValue

The normal behavior in my mind is the one that I have in the Main function.

Debugger.

4 Answers

private keyword
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...
It is a compile-time error to reference a private member outside the class or the struct in which it is declared.

If you look at the documentation for the private keyword, the "key" part in relation to your question is that it is accessible within the body of the class and not restricted to access by only the same instance in which the private member or method is declared.

In your added example, TestMethod is in TestClass, so code in TestMethod can access any private methods or properties in its own instance and any other instance it has access to.

This is indicated in the quoted definition of the keyword: TestMethod is "in the body of the class in which _testValue is declared", so it can access those.

There is no restriction in the documentation that the access must be through a specific instance, so no matter how you create or have access to a new or different TestClass inside of TestMethod, you have access to that instance's private members and methods.

One of the reasons we have private is to keep internals away from unrelated code but to still provide access to the class it belongs to. This allows the class to manipulate instances of itself, which is incredibly important in copying internal data from one instance of an object to another. You don't want to make those public, because then any other unrelated code would have unwanted access.

This behavior of private is at least shared with C++ and TypeScript, and it probably common across most if not all programming languages the have public and private access.

Taken from documentation:

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, as in this example:

-snip-

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

It is a compile-time error to reference a private member outside the class or the struct in which it is declared.

As for your screenshot.. The value of first _testValue is at 0 because that's the default value of int and you didn't set anything else otherwise when you created that object.

The new object you've created inside TestClass - you're explicitly setting a value of 23 to that and you do this because you have access to that property as per definition of the private keyword.

Let me just refer to this specific part of your question - I think it should help you understand the behavior:

Place a debugger, you will see that the TestClass this._testValue is not the same as the t._testValue

Now, some clarification to all those private keyword definitions people posted here. Both private and protected access modifiers refer to a class not an object - that means that if a property is marked as private, then any object of that class can access that private property in any instance of the same class, including different objects. That's why the definiton specificly say:

Private members are accessible only within the body of the class or the struct in which they are declared.

It's the same if most (if not all) object-oriented programming language. The justification for that might be that if two objects belong to the same class, then they know how to properly and safely handle and use their private members - there is no point of restricting that access then.

You seem to assume that private cares for the instance - which it obviously does not. In fact you don´t even need an instance - e.g. on a static member.

So if or if not you may access a member of a class depends on two factors:

  1. are you within the same scope as that member?
  2. do you have access to the instance to which the member belongs?

In your case your member is private, which makes the members scope the class-level. TestMethod is a method within that class, so point one matches.

You have two different instances. As you´re within TestMethod you can of course access the members of this (the current instance). Furthermore you have a reference to the newly created instance t. So point 2 also applies and you can access both members of both instances.

As an aside to point 2: If the member is static, there´s no instance, you can allways access it from within another instance.

Related