c# - 如何覆盖计算值?

标签 c#

所以我有以下代码片段:

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>.Valuenull会给你一个编译器错误。将其设置为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/

相关文章:

c# - Windows Phone 8.1 中的环境变量

C# - 水印密码字符?

c# - 为什么 C# 的速度是 C++ 的两倍,即使生成的机器代码几乎相同?

c# - 调用 GC.SuppressFinalize(this) 时是否存在不使用 "this"的用例?

c# - 如何解析非结构化的 csv 文件

c# - 如何调查 Process.Start() 失败?

c# - 拍摄 IObservable<T> 的快照

c# - 如何在 mvc3 razor 中将 userid 从一种方法传递到另一种方法

c# - 具有自定义类型的路由不会显示在 Swagger 中

c# - Oracle NUMBER(10) 列报告为 Int64 而不是 Int32