tags:

views:

145

answers:

8

Hi,

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.

+4  A: 

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.

Mitchel Sellers
Woah! Sorry @Mitchel - I accidentally edited the wrong post. Sorry 'bout that.
Marc Gravell
@Marc - did you get bit by the lovely random ordering feature? I've had that happen more than once where I automatically assumed that my question was in the same position after an edit (or submission) and blindly clicked the edit button. Doesn't help when the answer in that position starts with virtually the same text.
tvanfosson
+2  A: 

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

Marc Gravell
`while(true)` plus `break` inside the loop's body is a perfectly valid programming construct. There is much worse things than that.
@ToxicAvenger - but *without* the `break`?
Marc Gravell
+1  A: 

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.

Justin Niessner
+1  A: 

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.

CkH
Arguably, it can go both ways: you may well want to reference the backing field directly so that you aren't affected by any addition to the public property. It would be a good idea to be consistent about this, however, and possibly a good idea to clearly identify backing variables that it's clear that a property is being bypassed. For example, you could suffix them with `_Prop` or something like that.
Steven Sudit
I prefer consistency and just wanted to point out the reason for the pattern. There's always a reason for every one off solution, doesn't make it best practice.
CkH
+3  A: 

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.

Dan Tao
SO what happens when you come back to the code in 6 months to add important logic to the property setter? All your class' internal code will now be bypassing the new implementations.
Dr Herbie
I prefer to default to using the property precisely because I don't want to keep track of places where the property does something special. The optimizer will typically take care of optimizing the method call out anyway, at least for a simple accessor. I'll only use the property when I know the property does something "special" and I want to avoid that for some particular purpose.
tvanfosson
@Dr Herbie: But in my experience it's just as likely that you'll add logic to the property but *won't* want that logic to be executed on every access happening within the class -- only on accesses from external code. I've definitely worked with developers who added logic to their properties and all of a sudden they found some of their code was getting executed way more often than they intended. It's a judgement call, obviously; I'm just pointing out that there's a difference between hiding your implementation from the outside world and hiding it from... itself.
Dan Tao
@Dan - I find that highly suspect reasoning. Typically, you put extra code into the property setter to enforce some dependency or business rule. My experience is that you generally *don't* want to avoid this, even in the class. There are certainly exceptions -- and I would reference the backing property in those cases -- but because they are exceptional I use the property in the default case rather than the other way around. Referencing your example, I would say that in the initializer using the field directly is fine, but anywhere else in your class, you really do want to use the property
tvanfosson
@tvanfosson: Hey, I'm not saying you're wrong. My perspective is basically this: the OP seems to be looking for a way to disallow access to a private member from within an implementation. I'm saying: this is not *necessarily* something you need to do. As for what kind of logic should or should not go into a property getter/setter, that's a different argument. In any case, we both seem willing to concede that *sometimes* one approach is reasonable and *sometimes* the other approach makes more sense; that's all I'm really trying to argue -- not which one is the exception and which is the rule.
Dan Tao
+2  A: 

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
}
Jesse C. Slicer
Yes, but... yuck.
tvanfosson
I never claimed it was good. Just that it could be done.
Jesse C. Slicer
A: 

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.

Joe White
+1  A: 

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.

Jon Skeet
+1 - I agree completely with the privately scoped property variable. I'd really like the ability both to have arbitrary code in the property methods **and** limit access to the backing field to the property only so that I don't accidentally avoid the "rules" in the getter/setter code.
tvanfosson