代码之家  ›  专栏  ›  技术社区  ›  Joseph Ferris

基类对派生类中属性变化的认识

  •  3
  • Joseph Ferris  · 技术社区  · 15 年前

    我想知道是否有人可以解决以下问题…我有一个派生类系列将从中继承的基类。基类关心派生类上的属性是否已更改。这是为数据传输对象设置“isdirty”方法。

    传统的方法是设置一个在基类中声明的isdirty布尔标志。我本来想以某种方式避免这种情况,想知道是否还有其他的方法?我担心开发人员不记得在派生类中的属性的等效set操作中设置标志。我曾考虑过创建一个通用的“setproperty”方法,该方法将采用属性名和值,但我认为可能会有更优雅的东西。

    正如旁注,关于使用反射的想法不是问题。不管反射的代价是什么,我都想证明一种方法来实现它,并在今后进一步改进它。

    3 回复  |  直到 15 年前
        1
  •  3
  •   Benjamin Podszun    15 年前

    可以强制派生类实现inotifyPropertyChanged吗?在这种情况下,我将向基类constructur和chill中的propertychanged事件添加一个侦听器。派生类现在仍然需要遵循模式(您可能希望避免哪种情况?).

    对于引发属性更改事件的“不使用字面字符串”方法,阅读起来很好: http://monotorrent.blogspot.com/2009/12/yet-another-inotifypropertychanged-with_06.html

        2
  •  1
  •   richj    15 年前

    控制对类(或一组类)的访问的适当模式是代理模式。此模式允许您在代理级别实现正确的isdirty行为,并将任何只读行为委托给未更改的实际实例。

    当与工厂模式一起使用以控制实例的创建时,此模式最有效。

    此解决方案将屏蔽实例的运行时类型,因此,如果您的设计依赖于运行时类型信息,您将需要单独解决此问题(例如,使用状态模式),或者找到另一种方法。

        3
  •  0
  •   zincorp    15 年前

    (快速和肮脏)-像这样的东西怎么样?(您对gethashcode的实现可能会有所不同-我使用resharper自动生成这个代码)

        public abstract class Animal
        {
            private int _originalHash;
    
            public string Name { get; set; }
            public int Age { get; set; }
    
            public Animal(string name, int age)
            {
                this.Name = name;
                this.Age = age;
    
                this._originalHash = GetHashCode();
            }
    
    
            public override sealed int GetHashCode()
            {
                unchecked
                {
                    return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ Age;
                }
            }
    
            public bool IsDirty
            {
                get
                {
                    return this._originalHash != GetHashCode();
                }
            }
        }
    
        public class Cat : Animal
        {
            public Cat(string name, int age)
                : base(name, age)
            {
            }
        }
    

    用这个来测试…

    var cat = new Cat("BobTheCat", 12);
    Console.WriteLine(cat.IsDirty);
    cat.Age = 13;
    Console.WriteLine(cat.IsDirty);
    

    结果如下:

    假 真