【问题标题】:Get the changed properties in same object获取同一对象中更改的属性
【发布时间】:2014-07-06 05:48:39
【问题描述】:

我有一个具有五个属性的对象,每个属性都有两种状态(“之前”和“之后”)。

如何获取有关哪些属性更改了状态的信息?

我熟悉的唯一方法是获取所有属性的列表(使用反射?),然后使用循环比较两个对象之间的每个属性并存储有关已更改对象的信息。

有没有简单的方法,也许使用 LINQ?

【问题讨论】:

  • @EZI-Ive 已经阅读过它,但不明白它对我有何帮助,因为我如何才能获得已更改的属性,例如,如果 f2 和 f3 已更改...
  • @M.Herbert 不知道你为什么要标记这个 LINQ

标签: c#


【解决方案1】:

接口INotifyProprtyChanged要求你实现一个事件PropertyChanged。您可以在类本身中订阅此接口并跟踪调用它们的属性。

例如:

internal class SampleClass : INotifyPropertyChanged{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _SampleProperty;
    internal List<string> _ChangedProperties;

    public SampleClass() {
      this.PropertyChanged += SampleClass_PropertyChanged;
      _ChangedProperties = new List<string>();
    }

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

    void SampleClass_PropertyChanged( object sender, PropertyChangedEventArgs e ) {
      if ( _ChangedProperties.Contains( e.PropertyName ) ) return;
      _ChangedProperties.Add( e.PropertyName );
    }

    public string SampleProperty {
      get { return _SampleProperty; }
      set {
        if (_SampleProperty == value )
          return;
        _SampleProperty = value;
        OnPropertyChanged( "SampleProperty" );
      }
    }
}

现在您有了一个已更改属性的列表。您可以通过记住值等来进一步工作。

我没有考虑线程安全,我不会考虑这个示例生产就绪。

【讨论】:

  • 类公开事件的一个常见约定是实现一个带有On前缀的受保护虚拟方法(即在这种情况下为OnPropertyChanged),它在调用时实际调用事件。它减少了代码重复(每次调用的空检查)并消除了将类附加到自己的句柄的需要(所有与事件相关的功能都可以在该方法中实现)。
  • @Groo 没错——我提到这个示例的另一个原因是不是生产代码。不过会更新我的问题
  • @Sascha-thanks 投了赞成票,我肯定会尝试一下,我的问题是假设我有 F1-F10 字段,我是否需要对所有字段都这样做(你为示例属性做了什么?或者有更短的方法吗?2.假设我有来自同一个类的 Obj1 和 object2,这是找到已更改属性的最佳方法?
  • 您也可以:void OnPropertyChanged([CallerMemberName] string propertyName = ""),然后直接拨打:OnPropertyChanged()。检查此:msdn.microsoft.com/en-us/library/… 了解更多详情:D
  • @M.Herbert 您需要在所有字段上支持INotifyPropertyChanged 机制。每个类都包含自己更改的字段,如果您想针对另一个对象跟踪它而不是需要比较
【解决方案2】:

你可以这样做:

public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
public class PropertyChangedEventArgs : EventArgs
{
    public PropertyChangedEventArgs(string propertyName, dynamic oldValue, dynamic newValue)
    {
        this.PropertyName = propertyName;
        this.OldValue = oldValue;
        this.NewValue = newValue;
    }

    public virtual string PropertyName { get; private set; }
    public virtual dynamic OldValue { get; private set; }
    public virtual dynamic NewValue { get; private set; }
}

public class PropertyClass
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void Set<T>(string propertyName, ref T field, T value)
    {
        if (field.Equals(value))
            return;

        T oldValue = value;
        field = value;

        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName, oldValue, value));
    }

    // Properties
    private string _name;
    private string _message;
    private bool _isMember;

    public string Name
    {
        get { return _name; }
        set { Set("Name", ref _name, value); }
    }

    public string Message
    {
        get { return _message; }
        set { Set("Message", ref _message, value); }
    }

    public bool IsMember
    {
        get { return _isMember; }
        set { Set("IsMember", ref _isMember, value); }
    }
}

【讨论】:

    猜你喜欢
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多