c# /WinForms/INotifyPropertyChanged:当一个或两个操作数可能为空时,检查相等的优雅方式

本文关键字:检查 方式 两个 INotifyPropertyChanged WinForms 一个 操作数 | 更新日期: 2023-09-27 18:06:04

我有一个类栏实现INotifyPropertyChanged。当设置属性CurrentFoo时,如果值正在变化,我想引发PropertyChanged。Foo实现了等价操作符,但不实现==操作符。

目前我的代码是这样的:

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)…但是,废话。当然,我错过了一个方便的类库方法,尽管我已经检查过了。

c# /WinForms/INotifyPropertyChanged:当一个或两个操作数可能为空时,检查相等的优雅方式

测试其中一个值是否为null就足够了,因为如果参数为null, Equals方法应该返回false:

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

或者,你可以使用Foo的默认的EqualityComparer来检查null并调用Equals方法:

if (!EqualityComparer<Foo>.Default.Equals(this.FooValue, value))
{
    this.fooValue = value;
    this.OnPropertyChanged("CurrentFoo");
}

这是内置于。net框架内的,将会做这些

if (!System.Collections.Generic.EqualityComparer<Foo>.Default.Equals(value, fooValue))
{
    // value changed logic here.
}

嗯,可能是这样的:

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

似乎可以在这里使用扩展方法:

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

如果我不想使用EqualityComparer,我会这样写:

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

我认为这是我能做到的最优雅的了。