C# 当一个属性快速更改多次时,会发送多少个PropertyChanged事件?

C# 当一个属性快速更改多次时,会发送多少个PropertyChanged事件?,c#,inotifypropertychanged,C#,Inotifypropertychanged,我有一些实现PropertyChanged事件的代码(类似于下面的代码段) 我注意到我的事件处理程序只被调用了一次,当同一属性被快速更改了几次时。我找不到任何文件提到这一点。有人能确认这是否是PropertyChanged的预期行为吗?您显示的代码将调用事件的委托,调用次数与调用SendPropertyChanged的次数相同。这里没有魔法。但是,一种常见的方法(返回代码中未显示的级别)是检查实际更改,例如: private int id; public int Id { get { r

我有一些实现PropertyChanged事件的代码(类似于下面的代码段)


我注意到我的事件处理程序只被调用了一次,当同一属性被快速更改了几次时。我找不到任何文件提到这一点。有人能确认这是否是PropertyChanged的预期行为吗?

您显示的代码将调用事件的委托,调用次数与调用
SendPropertyChanged
的次数相同。这里没有魔法。但是,一种常见的方法(返回代码中未显示的级别)是检查实际更改,例如:

private int id;
public int Id {
    get { return id; }
    set {
        if(id != value) {
            id = value;
            SendPropertyChanged(); // let C# 5 compiler tricks supply the name
        }
    }
}
private void SendPropertyChanged([CallerMemberName]string propertyName = null)
{
    var handler = PropertyChanged;
    if(handler != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
    }
}
带测试:

    var obj = new Foo();
    int count = 0;
    obj.PropertyChanged += delegate { count++; };

    obj.Id = 1;
    obj.Id = 2;
    obj.Id = 3;

    Console.WriteLine(count); // outputs: 3

    count = 0;
    obj.Id = 1;
    obj.Id = 1;
    obj.Id = 1;

    Console.WriteLine(count); // outputs: 1

显示的代码调用事件委托的次数与调用
SendPropertyChanged
的次数相同。这里没有魔法。但是,一种常见的方法(返回代码中未显示的级别)是检查实际更改,例如:

private int id;
public int Id {
    get { return id; }
    set {
        if(id != value) {
            id = value;
            SendPropertyChanged(); // let C# 5 compiler tricks supply the name
        }
    }
}
private void SendPropertyChanged([CallerMemberName]string propertyName = null)
{
    var handler = PropertyChanged;
    if(handler != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
    }
}
带测试:

    var obj = new Foo();
    int count = 0;
    obj.PropertyChanged += delegate { count++; };

    obj.Id = 1;
    obj.Id = 2;
    obj.Id = 3;

    Console.WriteLine(count); // outputs: 3

    count = 0;
    obj.Id = 1;
    obj.Id = 1;
    obj.Id = 1;

    Console.WriteLine(count); // outputs: 1
请记住,C#事件实际上只是一个函数调用。与常规函数调用相比,有两个主要区别:-

  • 对于事件,被调用方依赖于调用方,而不是相反

  • 事件可以有一个调用列表,也就是说,可以将多个被调用方附加到一个调用方

  • 事件引发机制中没有内置节流功能,因此您看到的效果必须有不同的解释。

    请记住,C#事件实际上只是一个函数调用。与常规函数调用相比,有两个主要区别:-

  • 对于事件,被调用方依赖于调用方,而不是相反

  • 事件可以有一个调用列表,也就是说,可以将多个被调用方附加到一个调用方


  • 事件引发机制中没有内置节流功能,因此您看到的效果必须有不同的解释。

    您怎么知道它只被调用一次?也许您更改属性的方式实际上是更改私有成员,而只有一个位置设置属性?非常感谢您的所有回答。调用SendPropertyChanged是一个愚蠢的错误。你怎么知道它只被调用一次?也许您更改属性的方式实际上是更改私有成员,而只有一个位置设置属性?非常感谢您的所有回答。调用SendPropertyChanged是一个愚蠢的错误。