c#类的自动更新

  • 本文关键字:更新 c# auto-update
  • 更新时间 :
  • 英文 :


我首先请求您帮助一个表示齿轮的类。我希望当Z或m_0属性的值发生变化时,Update()过程会自动运行,以便执行d_0属性的更新。但是,我不想直接在get块中执行计算,因为我采用的示例很简单,但是有些计算处理起来特别长,我不想每次尝试读取属性时都重复计算。

public class ToothedWheel
{
public ToothedWheel(int Z = 16, double m_0 = 8)
{
this.Z = Z;
this.m_0 = m_0;
}
public void Update()
{
d_0 = m_0 * Z;
}
public int Z { get; set; } // Z Tooth number
public double m_0 { get; set; } // m_0 Module (mm)
public double d_0 { get; private set; } // Pitch diameter (mm)
}

我还需要一个类代表齿轮(2齿轮)的帮助。在这类中,小齿轮的m_0属性值必须等于车轮的m_0属性值。为了实现这一点,我定义了一个get块和一个set块,但是我仍然可以通过直接通过ToothedWheel类访问m_0属性。我如何正确包装我的类,以允许Z属性直接通过tothedwheel类更改,但避免m_0属性被更改。

public class Gear
{
public Gear()
{
Pinion = new ToothedWheel();
Wheel = new ToothedWheel();
}
public ToothedWheel Pinion, Wheel;
private double _m_0;
public double m_0
{
get { return _m_0; }
set
{
_m_0 = value;
Pinion.m_0 = _m_0;
Wheel.m_0 = _m_0;
}
}
}

我不知道如何解决我的问题,我在论坛上找不到答案。

要确保Update只在请求值时被调用一次,并且重复的请求不会造成额外的负载,您应该执行如下操作:

对依赖值m_0Z的任何更新都将迫使d_0在下一次get访问时重新计算,但会导致进一步的请求回退到先前计算的值。

public class ToothedWheel
{
private int z;
private double m0;
private double d0;
private bool calculated;
public ToothedWheel(int Z = 16, double m_0 = 8)
{
this.Z = Z;
this.m_0 = m_0;
}
private void Update()
{
d0 = m0 * z;
calculated = true;
}
// Z Tooth number
public int Z
{
get => z;
set
{
if (z != value)
{
z = value;
calculated = false;
}
}
}
// m_0 Module (mm)
public double m_0 {
get => m0;
set
{
if (m0 != value)
{
m0 = value;
calculated = false;
}
}
}
// Pitch diameter (mm)
public double d_0
{
get
{
if (!calculated)
{
Update();
}
return d0;
}
}
}

我还建议您使用更有意义的属性名称,例如:

  • Z=>Teeth
  • m_0=>Module
  • d_0=>PitchDiameter

它可能更冗长,但确实有助于可读性和可维护性。

首先:

有些计算处理时间特别长

你计算过这些计算需要多长时间吗?虽然避免重复计算是一种很好的方法,但cpu的速度,只要你做简单的数学运算,它就可以在人类可测量的任何时间内完成大量的计算。

但是,如果写入该值的次数多于读取该值,则在设置该值时计算该值可能会导致问题。一种常见的解决方法是在第一次读取值时进行计算,并将其缓存以供后续读取。您可以为此使用Lazy<T>,在参数更改时重新创建惰性对象,并在读取该值时获取该值。

在这个类中,小齿轮的m_0属性值必须等于车轮的m_0属性值。

那么你的类应该强制这样做,例如你可以使用接口:

public IToothedWheel{
public double m_0 { get; }
}
public class Gear
{
private ToothedWheel pinion;
private ToothedWheel wheel;
public IToothedWheel Pinion => pinion;
public IToothedWheel Wheel => wheel;
public double m_0
{
get { return _m_0; }
set
{
_m_0 = value;
pinion.m_0 = _m_0;
Wheel.m_0 = _m_0;
}
}
}

这将使任何外部人员不可能使小齿轮和车轮的值不同,至少在不检查运行时类型的情况下。

另一种方法是创建组件图,并在任何更改之后使用单独的验证检查器,如果安排无效,将给出错误,并让用户纠正问题。

最新更新