Reputation: 8336
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
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
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
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
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
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
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