很抱歉这个问题很长!我一直在尝试使用get / set访问器,但我遇到了一个问题。
举一个例子,我有一个Vector2D类,它具有私有的双x和y值以及这些值的公共访问器X和Y.我还有一个公共Direction属性(自定义类型Angle,它本身具有公共双度和Radians属性)。这个Direction属性有一个 get 访问器,它根据X和Y的值返回一个新的Angle对象,以及一个 set 访问器,它根据颜色改变X和Y值。传入新的角度值。
因此,如果你有一个名为vector的Vector2D,你可以使用vector.Direction = new Angle(0),它可以正常工作。但自然也可以编写vector.Direction.Degrees = 0.这不会导致错误,但它也不能按预期工作,因为矢量的x和y值不会更新。
在考虑之后,我理解为什么会发生这种情况。当你编写vector.Direction.Degrees时,它使用Vector2D中的 get 访问器,它返回一个基于X和Y的新角度,然后它访问Degrees属性及其 set 对象的访问器,而不是原始矢量对象上的Direction属性的 set 访问器。换句话说,vector.Direction上的 set 访问器根本不会在该场景中使用,因此不会更新x和y值。我认为这是有道理的。
您可以访问vector.Direction.Degrees并尝试将其设置为其他值,但这实际上并没有做任何事情,这显然令人困惑。但我也看到这种行为是有意的。我的问题是,处理这个问题的好方法是什么?
提前致谢!
编辑 - 这是我班级定义的相关部分:
Vector2D类
private double x;
private double y;
public double X { get => x; set => x = value; }
public double Y { get => y; set => y = value; }
public Angle Direction
{
get
{
return new Angle(X, Y);
}
set
{
double previousMagnitude = Magnitude;
X = Math.Cos(value.Radians) * previousMagnitude;
Y = Math.Sin(value.Radians) * previousMagnitude;
}
}
答案 0 :(得分:0)
(最)正确的做法是使 Angle 不可变,以便在创建后无法更改其度和弧度。您可能需要静态工厂方法Angle.FromDegrees()和Angle.FromRadians(),因为度和弧度都是双倍的,因此您不能使用.ctor重载。
如果失败,你需要在Angle上创建Changed事件,为这个事件订阅Vector2D,每次设置Degrees或Radians时都要提升它。当重新分配Vector2D.Angle时也取消订阅...这似乎是一个巨大的矫枉过正,尤其是。如果可以在矢量之间共享角度对象。
答案 1 :(得分:0)
由于每次访问时都会返回一个新的Direction值,我建议不要在Direction.Degrees和Direction.Radians中设置公共设置,如下所示:
public double Degrees
{
get { /* return degrees */ }
private set { /* set degrees, but only from somewhere in the struct, for example the constructor */ }
}
并像这样使用它:
public Angle(double X, double Y)
{
this.Degrees = /*do computation based on X and Y*/;
this.Radians = /*do computation...*/
}
由于保护级别导致属性无法访问而产生错误:
myVector2D.Direction.Degrees = x;
使用:
myVector2D.Direction = new Angle(x, y);
通过这种方式,您可以强制用户使用Vector2D.Direction而不是Angle.Degrees,这样您就可以检测并对任何更改做出反应。
对于任何格式错误感到抱歉,我正在使用手机。