DevinB
DevinB

Reputation: 8336

force get/set access of private variables for private properties

If I have a private variable that I want to have some internal validation on, and I want to keep that validation in one place, I put it behind a getter/setter and only access it thorugh that getter/setter. That's useful when dealing with public properties, because the other code cannot access the private variable, but when I'm dealing with object inside the class itself, is there any way to enforce the getter/setter?

  private int _eyeOrientation;

  private int eyeOrientation
  {
     get
     {
        return _eyeOrientation;
     }
     set
     {
        if (value < 0)
        {
           _eyeOrientation = 0;
        }
        else
        {
           _eyeOrientation = value % 360;
        }
     }
  }

The issue here being that the other functions in the class may accidentally modify

_eyeOrientation = -1;

which would throw the program into a tizzy. Is there any way to get that to throw a compiler error?

Upvotes: 6

Views: 4634

Answers (6)

LukeH
LukeH

Reputation: 269628

You can mark the field as obsolete so that the compiler will generate a warning if you try to access it, and then suppress that warning for the property getter/setter.

The warning codes that you'd need to suppress are CS0612 for the plain Obsolete attribute and CS0618 if the attribute has a custom message.

In general I'd consider this a bit of a hack and try to avoid it if possible. A better solution would be to comment the code appropriately and train your fellow developers so that they'll do the right thing.

[Obsolete("Please use the EyeOrientation property instead.")]
private int _eyeOrientation;

public int EyeOrientation
{
    #pragma warning disable 612, 618
    get
    {
        return _eyeOrientation;
    }
    set
    {
        _eyeOrientation = (value > 0) ? value % 360 : 0;
    }
    #pragma warning restore 612, 618
}

Upvotes: 3

Fredrik Leijon
Fredrik Leijon

Reputation: 2802

Depending on your tools you could look into enforcing a coding convention not allowing direct access to a private member outside a get/set

Might be some more work but you won't have to create a series of wrapper classes.

Upvotes: 1

Stefan Steinegger
Stefan Steinegger

Reputation: 64648

Sounds like you need a angle type.

// Non mutable Angle class with a normalized, integer angle-value
public struct Angle
{
  public Angle(int value)
  {
    Value = value;
  } 

  private angle;
  public Value 
  { 
    get { return angle; } 
    private set { angle = Normalize(value); } 
  }

  public static int Normalize(int value)
  {
     if (value < 0) return 360 - (value % 360);
     return value % 360;
  }
}

public class SomeClass
{
  public Angle EyeOrientation { get; set; }
}

If you have a certain kind of value, like angles, money, weight or whatever, it is always a good praxis to make it a own type, even if the value itself is stored in a int, decimal etc. This type makes your interfaces clearer and typesafe. It is not the same if you expect an Angle or a integer value as argument of some method.

Upvotes: 10

Reed Copsey
Reed Copsey

Reputation: 564861

In general, you shouldn't worry about this. Class members can still use the properties, if you don't want to put the checking in the class itself.

If your class is getting so large that you no longer trust methods inside the class, I'd think that it's time to start refactoring and breaking this into smaller classes that are more easily managable.

Upvotes: 9

James Black
James Black

Reputation: 41848

Just put your private attribute and public getters/setters into a private class.

Then only the getter and setter can access the private attribute.

It is overkill but would work. :)

Upvotes: 1

Martin
Martin

Reputation: 6032

You could possibly define it in a nested class.

public class NeedsEye
{

    Eye _eye = new Eye();

    public NeedsEye()
    {
        // now, here, any access to the property must be made through the
        // _eye variable. The Eye class has access to any of the properties
        // and members of the NeedsEye class, but the NeedsEye class has not
        // any access to members of the Eye class.
    }

    private class Eye
    {
        private int _orientation;

        public int Orientation 
        {
            get { return _orientation; }

            if (value < 0)
            {
               _eyeOrientation = 0;
            }
            else
            {
               _eyeOrientation = value % 360;
            }     
        }
    }
}

Upvotes: 4

Related Questions