adamwtiko
adamwtiko

Reputation: 2905

Blocking access to private member variables? Force use of public properties?

I'm using .NET 2.0 so do not have access to automatic properties. So I must resort to the following way of coding private variables and public properties

private string m_hello = null;

public string Hello
{
     get{return m_hello;}
     set{m_hello = value;}
}

For methods of the containing class of the above private/public members, is there anyway to restrict access to the private variable? I do not like that I can either use m_hello or Hello.

Thanks.

Upvotes: 12

Views: 3700

Answers (9)

WBuck
WBuck

Reputation: 5503

I believe in C#10, or at least a proposal for it, you can use semi-auto properties.

We can now use the field keyword in place of a backing property field.

So this:

private int _theNumber;
public int TheNumber 
{
    get => _theNumber;
    set => _theNumber = value;
}

Becomes this:

public int TheNumber
{
    get => field;
    set => field = value;
}

Granted in the example I provided an auto property would make more sense, but I wanted to show a simple example.

Upvotes: 0

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

You can accomplish this via inheritance:

abstract class A // A is not instantiatable due to being abstract
{
    private string m_hello = null;

    public string Hello
    {
         get{return m_hello;}
         set{m_hello = value;}
    }
}

class B : A
{
    // B now cannot access the private variable, use B in your code instead of A
}

I am not claiming that this is good. Just that it can be done.

Upvotes: 8

Jon Skeet
Jon Skeet

Reputation: 1499950

As others have suggested this should be an answer...

You can still use automatic properties in C# 3 when targeting .NET 2.0, along with quite a few other C# 3 features. Unlike (say) expression trees, automatic properties don't need anything special from the CLR or the framework, beyond the [CompilerGenerated] attribute (which was introduced in .NET 2.0).

So if you're using VS2008 or VS2010, then it would be worth using an automatic property.

For what it's worth though, I'd like this ability too. I'd like to be able to scope variables within a property:

 public string Name
 {
     private string name;
     get { return name; }
     set { name = value; }
 }

I view this a bit like making a private variable readonly - it makes no difference to clients, but it helps to enforce correctness within the class code itself.

Upvotes: 13

Joe White
Joe White

Reputation: 97666

If you find yourself wanting to hide details from yourself, that may be a code smell that your class has too many responsibilities. Consider extracting one of the responsibilities into a new class.

Upvotes: 0

Dan Tao
Dan Tao

Reputation: 128317

Personally, I see nothing wrong with accessing the private member within the class. In fact that's what I typically do (unless there's logic within the property getter/setter that I always want to leverage).

It just makes sense to me: the code within the class constitutes that class's implementation; why hide an implementation from itself?

Here's an example of what I mean. Suppose I have some member, m_denominator, and I want it never to be zero:

private int m_denominator = 1;
public int Denominator
{
    get { return m_denominator; }
    set
    {
        if (value == 0)
            throw new ArgumentException("Denominator must not be zero.");
        m_denominator = value;
    }
}

I might say to myself: "OK, everywhere I set this value within this class, I should use Denominator to make sure I'm not setting it to zero." But I'm completely in control of what I'm setting Denominator to -- I'm inside the class! In this scenario, the point of the logic in the Denominator property is to protect the class from invalid values set by client code. There's no excuse for setting your internal state to some invalid value within the implementation of a class itself.

Of course this is not an absolute rule. There are surely times when using the property for its logic within a class may be a sensible choice as a protective measure; really, I'm just arguing that it's not wrong to access private members from within a class.

Upvotes: 1

Mitchel Sellers
Mitchel Sellers

Reputation: 63126

No there is not a way to do that, other than to simply follow your own convention and do this.Hello if you really need to go through your public property.

I don't see why you would need/want to do this either, as since it is your internal class, you are the one in control of the code and you can define what/how it is used, so there shouldn't be an issue.

Upvotes: 6

CkH
CkH

Reputation: 1295

You should only access the property through the public Hello property. This is the reason for this pattern. If you add any functionality to the get or set, if you are accessing the private instance, you will introduce bugs into your code. But the anwer is NO, you cannot prevent someone from calling the Private when they are inside your class changing your code.

Upvotes: 1

Justin Niessner
Justin Niessner

Reputation: 245399

No. Any method inside the class will have access to both.

Your team should standardize on which to use (Property or private variable).

Once you decide which to use, you could try to use a custom FxCop rule to enforce the standard.

Upvotes: 4

Marc Gravell
Marc Gravell

Reputation: 1062590

No, basically. Well, you could do something with compiler warnings via [Obsolete] and #pragma, but that would be excessive.

You could probably do it with tooling, but eventually you need to trust people not to do stupid things. After all, do you have special rules about:

while(true) { }

or do you just put that down to "don't be stupid"? ;p

Upvotes: 1

Related Questions