t3dodson
t3dodson

Reputation: 4007

C# Property Encapsulation

C# properties are one of the most expressive tools I've found in a c family language. My question is why can't the "backing" field be within the property block? What reasoning is this not allowed?

public int Salary //Compile error
{
    int salary = 1000;
    get {} //custom use of salary
    set {} 
}

I find it rather clunky to do the following

int salary = 1000; //poor encapsulation but working code

public int Salary
{
    get {} //edit the private field salary
    set {} 
}

I've done some optimization of some code by memozing properties using the following pattern

int field;
bool flag = false;
public int Field 
{
    get
    {
        if (flag)
            return field;
        flag = true;
        return field = expensiveOperation();
    }
}

I would really like to move these variables in the scope of the property since they have no reason to be in the scope of the instance

public int Field //compile error
{
    int field;
    bool flag = false;
    get
    {
        if (flag)
            return field;
        flag = true;
        return field = expensiveOperation();
    }
}

Upvotes: 3

Views: 320

Answers (2)

Volma
Volma

Reputation: 1345

I think having a field declaration inside the property scope would only make sense if that scope defined the life cycle of the field. But it doesn't. The field belongs to the class and exists as long as the instance of the class exists (for instance fields).

As for your lazy initialization pattern, take a look at Lazy class. It nicely encapsulates expensive initialization and also provides thread-safety.

Upvotes: 1

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

If you have property, which work with its own data, not related to object where property sits, then I think you should extract that property from your class. Intent of properties is to work with data which are related to class where property is declared, and have scope of whole class.

Also keep in mind - property is just a syntax sugar for pair of methods.


Side note: you can use Lazy<T> for lazy initialization of field. E.g.

Lazy<int> field = new Lazy<int>(() => expensiveOperation());

Upvotes: 5

Related Questions