代码之家  ›  专栏  ›  技术社区  ›  Carlo

间接财产通知

  •  2
  • Carlo  · 技术社区  · 15 年前

    这个问题看起来有点微不足道,但可能不是。我只是想知道以下两种情况中哪一种更适合间接财产通知,或者也许还有更好的方法。

    场景:

    我有两个属性,第一个是一个名为HoldingObject的对象,第二个是一个名为IsHoldingObject的布尔值,如果HoldingObject==null则为false,否则为true。我只是想知道什么是iHoldingObject的最佳通知机制:

    案例(A)-通知iHoldingObject从HoldingObject项目更改为:

    public class NotifyingClass1 : INotifyPropertyChanged
    {
        private object _holdingObject;
        public object HoldingObject
        {
            get { return _holdingObject; }
            set
            {
                if (_holdingObject != value)
                {
                    _holdingObject = value;
                    NotifyPropertyChanged("HoldingObject");
                    // Notify from the property that is being checked
                    NotifyPropertyChanged("IsHoldingObject");
                }
            }
        }
    
        public bool IsHoldingObject { get { return this.HoldingObject == null; } }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    
        #endregion
    }
    

    public class NotifyingClass2 : INotifyPropertyChanged
    {
        private object _holdingObject;
        public object HoldingObject
        {
            get { return _holdingObject; }
            set
            {
                if (_holdingObject != value)
                {
                    _holdingObject = value;
                    NotifyPropertyChanged("HoldingObject");
    
                    // 1) Set the property here
                    this.IsHoldingObject = _holdingObject != null;
                }
            }
        }
    
        private bool _isHoldingObject;
        public bool IsHoldingObject
        {
            get { return _isHoldingObject; }
            set
            {
                if (_isHoldingObject != value)
                {
                    _isHoldingObject = value;
    
                    // 2) Notify directly from the property
                    NotifyPropertyChanged("IsHoldingObject");
                }
            }
        }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    
        #endregion
    }
    

    我个人倾向于第一个,因为它需要更少的代码,但我不确定这样做是多么值得推荐。如果有其他更好的方法,请告诉我。

    3 回复  |  直到 14 年前
        1
  •  1
  •   Abe Heidebrecht    15 年前

    我几乎总是选第二个。这样,所有负责设置给定属性的代码都在一个地方。在这种特殊情况下,IsHoldingObject属性完全依赖于HoldingObject属性,因此它可能不适用。但一般来说,现在的代码可能更少了,但如果以后需要从其他地方更新该属性,会发生什么情况?

    帮助器方法可以很容易地减轻您所承受的痛苦(代码的详细程度),该方法用于设置视图模型中的属性(这可以存在于基类中):

    protected bool SetValue<T>(ref T field, T value, string propertyName)
    {
        if (!Equals(field, value))
        {
            field = value;
            NotifyPropertyChanged(propertyName);
            return true;
        }
    
        return false;
    }
    

    然后,您的属性变成:

    private object _holdingObject;
    public object HoldingObject
    {
        get { return _holdingObject; }
        set
        {
            if (SetValue(ref _holdingObject, value, "HoldingObject"))            
                this.IsHoldingObject = _holdingObject != null;
        }
    }
    
    private bool _isHoldingObject;
    public bool IsHoldingObject
    {
        get { return _isHoldingObject; }
        private set { SetValue(ref _isHoldingObject, value, "IsHoldingObject"); }
    }
    
        2
  •  1
  •   Simon Randy Burden    14 年前

    在大多数情况下,这并不重要。让我们看看选项

    • 每次都要计算。所以在这里,每当UI请求值时,您都在消耗CPU。但考虑到每次用户界面需要请求每秒100s的值时所需的CPU数量,您甚至会注意到一次命中。我怀疑你的用户界面会需要这个。
    • 存储值。你在消耗记忆。同样,除非您存储许多大型对象,否则这不是问题。

    所以我想这可以归结为你更容易阅读的东西。我更喜欢“每次计算”。然后用这个 http://code.google.com/p/notifypropertyweaver/ 它允许我写这段代码

    public class NotifyingClass1 : INotifyPropertyChanged
    {
        public object HoldingObject { get; set; }
    
        public bool IsHoldingObject { get { return HoldingObject == null; } }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    

    public class NotifyingClass1 : INotifyPropertyChanged
    {
        private object holdingObject;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public virtual void OnPropertyChanged(string propertyName)
        {
            var propertyChanged = PropertyChanged;
            if (propertyChanged != null)
            {
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public object HoldingObject
        {
            get { return holdingObject; }
            set
            {
                if (holdingObject !=value)
                {
                    holdingObject = value;
                    OnPropertyChanged("HoldingObject");
                    OnPropertyChanged("IsHoldingObject");
                }
            }
        }
    
        public bool IsHoldingObject { get { return (HoldingObject == null); } }
    }
    
        3
  •  0
  •   DHN    15 年前

    有趣的主意。我想,我应该使用BindingConverter方法,它将HoldingObject转换为您喜欢的值。

    我对其他意见很好奇。

    当做