DEV Community

Cover image for Property accessor overloading: bypassing private properties
Jacopo Valanzano
Jacopo Valanzano

Posted on

Property accessor overloading: bypassing private properties

In TypeScript, a parent class can declare a private property like this:

abstract class Test {
    private data: string;
}
Enter fullscreen mode Exit fullscreen mode

Although a child class cannot access this property directly, it can still do so using a getter method:

abstract class Test {
    private data: string;

    // Getter method
    public getData() { return this.data };
}
Enter fullscreen mode Exit fullscreen mode

Wouldn't it be awesome if you could use property accessor overloading to read the property instead?

abstract class Test {
    private data: string;
    ...

    // Property accessor overloading
    public data() {
        return this.data;
    }
}
Enter fullscreen mode Exit fullscreen mode

Or even better

abstract class Test {
    private data: string;
    ...

    // Property accessor overloading
    public get data() {
        return this.data;
    }
}
Enter fullscreen mode Exit fullscreen mode

Unfortunately, this is not possible in TypeScript.
Attempting it will result in a TS2300: Duplicate identifier 'data' error.

In PHP, however, this can be achieved using the magic methods __get and __set:

class Test
{
    private string $data = "Hello, World!";

    public function __get(string $name) {
        return $this->$name;
    }

    public function __set(string $name, $value) {
        $this->$name = $value;
    }
}
Enter fullscreen mode Exit fullscreen mode

And you could then use the Test object to retrieve the private property:

$test = new Test();

$test->data; // Returns "Hello, World!"

// Override the data property
$test->data = "New value";
Enter fullscreen mode Exit fullscreen mode

This is a clear demonstration of property accessor overloading. It makes sense because you might want to at least read the property, even if it is private. However, using accessor overloading to modify a private property could be considered bad practice in some cases, as it undermines encapsulation.

In C#, you can achieve similar behavior using the indexer feature or explicit properties with the get and set accessors. Here's how it works:

class Test  
{  
    private string data = "Hello, World!";  

    public object this[string property]  
    {  
        get => data;  
        set => data = value as string;  
    }  
}
Enter fullscreen mode Exit fullscreen mode

Now, you can access data as if it were a dynamic property:

Test test = new Test();

test["data"]; // Returns "Hello, World!"

// Override the data property
test["data"] = "New value";
Enter fullscreen mode Exit fullscreen mode

Unlike TypeScript, C# allows this kind of property accessor overloading using indexers. While this approach works, it should be used with caution, as it can reduce code clarity, or even defeat the purpose of encapsulation in private properties.

Top comments (0)