C#Properties,为什么在赋值之前检查相等性

时间:2011-08-16 07:01:52

标签: c# properties

为什么我看到人们实现这样的属性?
检查值是否等于当前值是什么意思?

public double? Price
{
    get
    {
        return _price;
    }
    set
    {
        if (_price == value)
            return;
        _price = value;
    }
}

4 个答案:

答案 0 :(得分:28)

在这种情况下,这将是没有意义的;然而,在存在相关副作用(通常是事件)的情况下,它避免了微不足道的事件。例如:

set
{
    if (_price == value)
        return;
    _price = value;
    OnPriceChanged(); // invokes the Price event
}

现在,如果我们这样做:

foo.Price = 16;
foo.Price = 16;
foo.Price = 16;
foo.Price = 16;

我们没有得到4个事件;我们得到最多1(如果已经是16,则可能是0)。

在更复杂的示例中,可能存在验证,更改前操作更改后操作。如果你知道它实际上并不是一个改变,那么所有这些都可以避免。

set
{
    if (_price == value)
        return;
    if(value < 0 || value > MaxPrice) throw new ArgumentOutOfRangeException();
    OnPriceChanging();
    _price = value;
    OnPriceChanged();
}

答案 1 :(得分:6)

这不是一个答案,更多:它是对索赔的基于证据的回应(在另一个答案中),检查比分配更快。简而言之:不,不是。没有区别无论。我得到(对于不可空的int):

AutoProp: 356ms
Field: 356ms
BasicProp: 357ms
CheckedProp: 356ms

(在连续运行中有一些小的变化 - 但基本上它们在任何合理的舍入中都需要完全相同的时间 - 当做5亿次时,我们可以忽略1ms的差异)

事实上,如果我们改为int?,我会得到:

AutoProp: 714ms
Field: 536ms
BasicProp: 714ms
CheckedProp: 2323ms

double?(如问题所示):

AutoProp: 535ms
Field: 535ms
BasicProp: 539ms
CheckedProp: 3035ms

所以这是 性能助手!

带有测试

class Test
{
    static void Main()
    {
        var obj = new Test();
        Stopwatch watch;
        const int LOOP = 500000000;
        watch = Stopwatch.StartNew();
        for (int i = 0; i < LOOP; i++)
        {
            obj.AutoProp = 17;
        }
        watch.Stop();
        Console.WriteLine("AutoProp: {0}ms", watch.ElapsedMilliseconds);

        watch = Stopwatch.StartNew();
        for (int i = 0; i < LOOP; i++)
        {
            obj.Field = 17;
        }
        watch.Stop();
        Console.WriteLine("Field: {0}ms", watch.ElapsedMilliseconds);

        watch = Stopwatch.StartNew();
        for (int i = 0; i < LOOP; i++)
        {
            obj.BasicProp = 17;
        }
        watch.Stop();
        Console.WriteLine("BasicProp: {0}ms", watch.ElapsedMilliseconds);

        watch = Stopwatch.StartNew();
        for (int i = 0; i < LOOP; i++)
        {
            obj.CheckedProp = 17;
        }
        watch.Stop();
        Console.WriteLine("CheckedProp: {0}ms", watch.ElapsedMilliseconds);

        Console.ReadLine();
    }
    public int AutoProp { get; set; }
    public int Field;

    private int basicProp;
    public int BasicProp
    {
        get { return basicProp; }
        set { basicProp = value; }
    }

    private int checkedProp;
    public int CheckedProp
    {
        get { return checkedProp; }
        set { if (value != checkedProp) checkedProp = value; }
    }
}

答案 2 :(得分:1)

假设我们不处理任何与变更相关的事件。 我不认为比较比分配更快。这取决于数据类型。假设你有一个字符串,在最坏的情况下,比例比一个简单的赋值长得多,其中成员只是改变对新字符串的引用的引用。 所以我的猜测是,在这种情况下最好立即分配。 在简单数据类型的情况下,它没有真正的影响。

答案 3 :(得分:-1)

这样,您不必重新分配相同的值。它只是更快地执行比较值。 AFAIK