INotifyPropertyChanged的和静态属性静态、属性、INotifyPropertyChanged

2023-09-03 17:07:43 作者:我不怕毕业,我怕的是离别

我追平自己在海里了一个简单的问题。我有一个类实现 INotifyPropertyChanged的。一些实例属性干将使用静态特性,因此它们的值可如果静态属性的变化而变化?这里有一个简单的例子。

I'm tying myself in knots over a simple problem. I have a class that implements INotifyPropertyChanged. Some of the instance properties' getters use static properties and thus their values may change if the static property changes? Here's a simplified example.

class ExampleClass : INotifyPropertyChanged
{

    private static int _MinimumLength = 5;
    public static int MinimumLength
    {
        get
        {
            return _MinimumLength;
        }
        set
        {
            if (_MinimumLength != value)
            {
                _MinimumLength = value;
                //WHAT GOES HERE
            }
        }
    }

    private int _length = -1;
    public int length
    {
        get
        {
            return (_length > _MinimumLength) ? _length : _MinimumLength;
        }
        set
        {
            var oldValue = (_length > _MinimumLength) ? _length : _MinimumLength;
            if (_length != value)
            {
                _length = value;
                var newValue = (_length > _MinimumLength) ? _length : _MinimumLength;
                if (newValue != oldValue)
                {
                    OnPropertyChanged("length");
                }
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

显然,如果静态属性 MinimumLength 然后改变每个实例的属性长度也可以改变。但是应该如何静态属性信号可能改变的情况下?它不能调用 OnPropertyChanged ,因为这不是一成不变的。

Clearly if the static property MinimumLength changes then every instance's property length may also change. But how should the static property signal the possible change to the instances? It cannot call OnPropertyChanged since that is not static.

我可以保持一个列表中的所有实例的一流水平,并在每一个调用一个方法,但不知何故,感觉有点小题大做。或者,我可以拉的静态属性出到一个单例类,但在逻辑上他们住在类级别。是否有一个既定的模式获得本产品或我应该考虑这个不同?

I could keep a list at the class level of all the instances and call a method on each one, but somehow that feels like overkill. Or I could pull the static properties out into a singleton class but logically they live at the class level. Is there an established pattern for this or should I be thinking about this differently?

推荐答案

如果你倾向于认为,设计的话,我会用像下面这样的解决方案去:

If you're inclined to maintain that design then I would go with a solution like the following:

public static int MinimumLength
{
    get { return _MinimumLength; }
    set
    {
        if (_MinimumLength != value)
        {
            _MinimumLength = value;
            OnGlobalPropertyChanged("MinimumLength");
        }
    }
}
static event PropertyChangedEventHandler GlobalPropertyChanged = delegate { };
static void OnGlobalPropertyChanged(string propertyName)
{
    GlobalPropertyChanged(
        typeof (ExampleClass), 
        new PropertyChangedEventArgs(propertyName));
}
public ExampleClass()
{
    // This should use a weak event handler instead of normal handler
    GlobalPropertyChanged += this.HandleGlobalPropertyChanged;
}
void HandleGlobalPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch (e.PropertyName)
    {
        case "MinimumLength":
            if (length > MinimumLength)
                length = MinimumLength;
            break;
    }
}

这是pretty的多少等同于维护实例的列表,但我觉得它更易于维护,更清晰。另外,你真的需要使用弱事件处理的策略,否则,你的情况下,将不会被垃圾回收,因为它们将始终与静态事件,就像一个GC根关联。

This is pretty much equivalent to maintaining a list of instances but I find it more maintainable and clearer. Also, you really need to use a weak event handler strategy, otherwise, your instances will not be garbage collected because they will always be associated with the static event which acts like a GC root.

您可以阅读更多关于疲软的事件处理程序下面的博客文章(这是我写的,所以我有偏见):

You can read more about weak event handlers in the following blog posts (which were written by me so I'm biased):

.NET弱事件处理程序 - 第一部分

.NET弱事件处理程序 - 第一部分

在一个不相关的注意你的code目前正在射击属性更改,而实际上该属性值并没有改变。例如:

In an unrelated note your code is currently firing property changed when in fact the property value did not change. For example:

设置MinimumLength 5; 设置长度为10; (因为从默认值0更改为5事件触发) 设置长度为11; (事件触发,但它不应该,因为长度仍然是5)