C # / WinForms / INotifyPropertyChanged: элегантный способ проверки на равенство, когда один или оба операнда могут быть нулевыми - PullRequest
1 голос
/ 20 августа 2011

У меня есть класс Bar, который реализует INotifyPropertyChanged.При установке свойства CurrentFoo я хочу поднять PropertyChanged, если значение меняется.Foo реализует IEquatable, но не оператор ==.

В настоящее время мой код выглядит следующим образом:

public class Bar : INotifyPropertyChanged
{
    // ...

    private Foo fooValue;

    /// <summary>
    /// Gets or sets the active Foo
    /// </summary>
    /// <value>The active Foo.</value>
    public Foo CurrentFoo
    {
        get
        {
            return this.fooValue;
        }

        set
        {
            // Notify listeners if value is changing.
            if (null == this.fooValue && null != value
                || null != this.fooValue && null == value
                || null != this.fooValue && null != value && !this.fooValue.Equals(value))
            {
                this.fooValue = value;
                this.OnPropertyChanged("CurrentFoo");
            }
        }
    }

   // ...
}

И он работает, но ... тьфу!Есть ли более элегантный / передовой метод выполнения этой проверки без восстановления шаблона объекта Null (несовместимого с остальной частью нашей кодовой базы)?

Я рассмотрел написание вспомогательного метода, такого как IsOneObjectNullButNotBoth (объект a, объект b) ... но, опять же, бла.Конечно, мне не хватает удобного метода библиотеки классов, хотя я уже проверил его.

Ответы [ 5 ]

4 голосов
/ 20 августа 2011

Достаточно проверить одно из значений для нуля, поскольку метод Equals должен возвращать false, если аргумент равен нулю:

if ((this.fooValue != value) ||
    (this.fooValue != null && !this.fooValue.Equals(value)))
{
    this.fooValue = value;
    this.OnPropertyChanged("CurrentFoo");
}

В качестве альтернативы, вы можете использовать EqualityComparer по умолчанию для Foo, который проверяет наличие нулей ивызывает метод Equals:

if (!EqualityComparer<Foo>.Default.Equals(this.FooValue, value))
{
    this.fooValue = value;
    this.OnPropertyChanged("CurrentFoo");
}
0 голосов
/ 20 августа 2011

Вот как бы я написал это, если бы не хотел использовать EqualityComparer:

if ((obj1 ?? obj2) != null && (obj1 == null || !obj1.Equals(obj2)))
{
    // objects are diffrent
}

Я думаю, что это настолько элегантно, насколько я могу это сделать.

0 голосов
/ 20 августа 2011

Ну, может быть так:

Должно работать.

    public Foo CurrentFoo
    {
        get
        {
            return this.fooValue;
        }

        set
        {
            // Notify listeners if value is changing.
            bool bok = false;
            if (this.fooValue !=null && !this.fooValue.Equals(value))
                bok = true;
            else if(this.fooValue ==null)
                 bok = (this.fooValue == value);
            if(bok) {
                this.fooValue = value;
                this.OnPropertyChanged("CurrentFoo");
            }
        }
    }
0 голосов
/ 20 августа 2011

Это встроено в .net Framework и будет делать именно это

if (!System.Collections.Generic.EqualityComparer<Foo>.Default.Equals(value, fooValue))
{
    // value changed logic here.
}
0 голосов
/ 20 августа 2011

Похоже, вы можете использовать метод расширения здесь:

    if(fooValue.IsChanged(value))
    {
    }
    static public class Ext {
      static public bool IsChanged(this Foo fooValue, Foo value) {
        return null == fooValue && null != value 
          || null != this.fooValue 
          && null == value 
          || null != this.fooValue 
          && null != value 
          && !this.fooValue.Equals(value));
       }
    }
...