所以我有以下代码片段:
private Nullable<decimal> _excessWages;
public decimal ExcessWages
{
get
{
return _excessWages ?? CalculateExcessWages();
}
set
{
if (value != CalculateExcessWages())
_excessWages = value;
else
_excessWages = null;
}
}
所以基本上我想要实现的行为是,如果字段留空或分配的值等于计算值,则使用计算值,否则存储分配的值。
我有很多字段需要支持这样的覆盖。这是实现这一目标的最佳方法吗?如果没有,你会建议什么?
最佳答案
我主要基于 Vlad 对此进行了一些研究。的建议。事实证明,您可以使用单个泛型类来抽象它。最终结果如下:
public class Overridable<T>
{
private Func<T> _calculate;
private readonly Func<T, T, bool> _compare;
protected T _t;
public Overridable(Func<T> calculate, Func<T, T, bool> compare)
{
_calculate = calculate;
_compare = compare;
}
public T Value
{
get { return _compare(_t, default(T)) ? _calculate() : _t; }
set { _t = _compare(value, _calculate()) ? default(T) : value; }
}
}
您需要传入一个比较委托(delegate),因为只有在子类中设置它时,类型才是已知的。就这么简单==
不会削减它。我采用了简单的方法并使用了 Func 委托(delegate),但如果由于某种原因必须针对 .NET 2.0 进行调整,则可以将其替换为普通委托(delegate)。
你会注意到我正在使用default(T)
而不是null
。这是有效的,因为 Nullable<T>
的默认值是 null
(或更准确地说,未定义,但结果是相同的)。
这不会阻止您尝试声明 Overridable<T>
对于不可为 null 的类型。你最终得到的不会是由于运行时错误,但它没有那么有用。尝试设置 Overridable<decimal>.Value
至null
会给你一个编译器错误。将其设置为default(decimal)
时将导致它恢复计算值。
我走这条路线是因为我正在使用的类的属性需要填充最终作为 xml 传输的可序列化对象。 xml 的架构包括定义为整数、小数和字符串混合的数字字段。
然后您可以像这样使用 Overriddable 类:
private Overridable<decimal?> _excessWages =
new Overridable<decimal?>(CalculateExcessWages, (x,y) => x == y);
public virtual decimal? ExcessWages
{
get
{
return _excessWages.Value;
}
set
{
_excessWages.Value = value;
}
}
我遇到的唯一问题是 CalculateExcessWages
是一个非静态方法,因此不能在字段初始值设定项中使用。由于类中的所有属性都是非静态的,因此我必须初始化构造函数中的所有支持字段。
关于c# - 如何覆盖计算值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2342924/