强制获取/设置私有属性的私有变量的访问权限

时间:2009-05-11 23:58:42

标签: c#

如果我有一个私有变量,我希望对其进行一些内部验证,并且我希望将该验证保存在一个地方,我将它放在getter / setter之后,只能通过getter / setter访问它。这在处理公共属性时很有用,因为其他代码无法访问私有变量,但是当我在类本身内部处理对象时,有没有办法强制执行getter / setter?

  private int _eyeOrientation;

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

这里的问题是班级中的其他功能可能会意外修改

_eyeOrientation = -1;

会让程序陷入困境。有没有办法让它抛出编译错误?

6 个答案:

答案 0 :(得分:10)

听起来你需要一个角度类型。

// 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; }
}

如果你有某种价值,比如角度,金钱,重量或其他什么,即使价值本身存储在int,decimal等中,它也总是一个很好的实践,即使它本身存储在int,decimal等中。使您的界面更清晰,更安全。如果您希望将Angle或整数值作为某个方法的参数,则不一样。

答案 1 :(得分:9)

一般来说,你不应该担心这一点。如果您不想将检查放在类本身中,则类成员仍然可以使用这些属性。

如果你的课程变得如此之大以至于你不再信任课堂内的方法,我认为现在是时候开始重构并将其分解成更易于管理的较小类。

答案 2 :(得分:4)

您可以在嵌套类中定义它。

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;
            }     
        }
    }
}

答案 3 :(得分:3)

您可以将该字段标记为过时,以便编译器在您尝试访问时生成警告,然后suppress that warning生成属性getter / setter。

您需要屏蔽的警告代码为CS0612 for the plain Obsolete attributeCS0618 if the attribute has a custom message

一般来说,我认为这有点像黑客,并尽可能避免它。更好的解决方案是适当地评论代码并培训您的开发人员,以便他们做正确的事情。

[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
}

答案 4 :(得分:1)

只需将您的私有属性和公共getter / setter放入私有类。

然后只有getter和setter才能访问private属性。

这太过分但会起作用。 :)

答案 5 :(得分:1)

根据您的工具,您可以考虑强制执行不允许直接访问get / set之外的私有成员的编码约定

可能需要更多工作,但您不必创建一系列包装类。