简体   繁体   English

C# 属性,为什么要在赋值前检查相等性

[英]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;我们没有得到 4 个事件; we get at most 1 (maybe 0 if it is already 16).我们最多得到 1(如果已经是 16,可能是 0)。

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 ):我得到(对于不可为空的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) (连续运行有一些小的变化——但基本上它们在任何合理的舍入中都花费完全相同的时间——当做 5 亿次的事情时,我们可以忽略 1 毫秒的差异)

In fact, if we change to int?其实如果我们改成int? I get:我得到:

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

or double?还是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 AFAIK

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM