C# 强制获取/设置对私有属性的私有变量的访问

C# 强制获取/设置对私有属性的私有变量的访问,c#,C#,如果我有一个私有变量,我想对其进行一些内部验证,并且我想将该验证保留在一个地方,我将它放在一个getter/setter后面,并且只通过该getter/setter访问它。这在处理公共属性时很有用,因为其他代码无法访问私有变量,但是当我处理类本身内部的对象时,有没有办法强制执行getter/setter private int _eyeOrientation; private int eyeOrientation { get { return _

如果我有一个私有变量,我想对其进行一些内部验证,并且我想将该验证保留在一个地方,我将它放在一个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;
        }
     }
  }
private int\u眼睛定位;
私家车
{
得到
{
返回方向;
}
设置
{
如果(值<0)
{
_眼方位=0;
}
其他的
{
_眼方位=值%360;
}
}
}
这里的问题是类中的其他函数可能会意外地修改

\u眼方位=-1


这将使该计划陷入混乱。有没有办法让它抛出编译器错误?

您可以在嵌套类中定义它

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;
            }     
        }
    }
}
公共类NeedsEye
{
眼睛=新的眼睛();
公共需要
{
//现在,在这里,任何对财产的访问都必须通过
//\u eye变量。eye类可以访问任何属性
//和NeedsEye班的成员,但NeedsEye班没有
//任何接触Eye类成员的权限。
}
私家侦探
{
私人国际导向;
公共int定位
{
获取{返回_方向;}
如果(值<0)
{
_眼方位=0;
}
其他的
{
_眼方位=值%360;
}     
}
}
}

只需将私有属性和公共getter/setter放入私有类中即可

然后只有getter和setter可以访问private属性


这是过分的,但会起作用。:)

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


如果您的类越来越大,以至于您不再信任类内的方法,我认为是时候开始重构并将其划分为更小的类,以便更容易管理。

听起来您需要一个角度类型

// 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值)
{
价值=价值;
} 
私人角度;
公共价值
{ 
获取{返回角度;}
私有集{angle=Normalize(value);}
}
公共静态int规范化(int值)
{
如果(值<0)返回360-(值%360);
返回值%360;
}
}
公共类
{
公共角度眼定向{get;set;}
}

如果您有某种类型的值,比如角度、金钱、重量等,那么将其作为自己的类型始终是一种好做法,即使该值本身存储在int、decimal等格式中。这种类型使您的接口更清晰,类型更安全。如果您希望某个方法的参数为角度或整数值,则情况就不同了。

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


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

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

需要抑制的警告代码为和

一般来说,我会认为这有点麻烦,如果可能的话,尽量避免这样做。更好的解决方案是对代码进行适当的注释,并培训您的开发伙伴,以便他们能够做正确的事情

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

这是一个悲哀的日子,程序员不再信任同一类中的其他函数:)(+1)这是一个巧妙的解决方案这是个好主意,但我不会将其设置为0,因为负角度可以标准化为正角度,例如-10°==350°。@Stefan,我同意。我只是复制了问题中示例代码的功能。我正在一个个人项目中工作,我试图对访问权限尽可能严格。只是想看看是否有可能让所有的对象只被需要它们的对象访问。如果您坚持良好的编码实践,就不需要这些,但我很好奇这是否可能。