开发者

C# Properties, Why check for equality before assignment

Why do I see people implement properties like开发者_运维知识库 this?

What is the point of checking if the value is equal to the current value?

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


In this case it would be moot; however, in the case where there is an associated side-effect (typically an event), it avoids trivial events. For example:

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

Now, if we do:

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

we don't get 4 events; we get at most 1 (maybe 0 if it is already 16).

In more complex examples there could be validation, pre-change actions and post-change actions. All of these can be avoided if you know that it isn't actually a change.

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


This is not an answer, more: it is an evidence-based response to the claim (in another answer) that it is quicker to check than to assign. In short: no, it isn't. No difference whatsoever. I get (for non-nullable int):

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

(with some small variations on successive runs - but essentially they all take exactly the same time within any sensible rounding - when doing something 500 MILLION times, we can ignore 1ms difference)

In fact, if we change to int? I get:

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

or double? (like in the question):

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

so this is not a performance helper!

with tests

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; }
    }
}


Let's suppose we don't handle any change related events. I don't think comparing is faster than assingment. It depends on the data type. Let's say you have a string, Comparison is much longer in the worst case than a simple assignment where the member simply changes reference to the ref of the new string. So my guess is that it's better in that case to assign right away. In the case of simple data types it doesn't have a real impact.


Such that, you dont have to re-assign the same value. Its just faster execution for comparing values. AFAIK

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜