在类层次结构中传播属性值

时间:2011-01-26 23:36:46

标签: c# .net oop

我想将属性从子类传播到父类, 即:如果 MySchool.ModifiedTime 被更改,它也应该更改学生班中的ModifiedTime,如明智的 LstBook [0] .ModifiedTime 更改它应该更改 MySchool。 ModifiedTime 以及 Student.ModifiedTime ...(基本上ModifiedTime应该同步),任何想法

我正在寻找BaseClass中的通用函数来实现这一目标。

public class MyBaseClass
{
  public DateTime ModifiedTime{ get; set; }
}

public class Student: MyBaseClass
  {       
 public string Name { get; set; }
 public school MySchool {get;set;} 
 }

public class School : MyBaseClass
{
 public string SchoolName { get; set; }
 public List<Book> LstBook {get;set;}
}

public class Book:MyBaseClass
{
  public string BookName{get;set;}
}

5 个答案:

答案 0 :(得分:3)

您可以将ModifiedTime设为虚拟,然后在每个子类中覆盖它以执行同步。

public class MyBaseClass
{
  public virtual DateTime ModifiedTime{ get; set; }
}

public class Student: MyBaseClass
{       
  public string Name { get; set; }
  public school MySchool {get;set;} 
  public virtual DateTime ModifiedTime
  { 
    get {
       return MySchool.ModifiedTime;
    }
    set {
       MySchool.ModifiedTime = value;
    }
  }
}

等等。

但是,我会重新考虑你的类层次结构,因为它似乎是因素分析不正确。如果所有属性需要在整个层次结构中同步,则可能只有一个类应该具有该属性,而其他类应该引用它。例如,只有School应该具有ModifiedTime属性,当您需要为学生获取修改时间时,您将通过MySchool属性

检索它

答案 1 :(得分:2)

您似乎误解了对象层次结构的工作原理。

将它实现为类成员只将它链接到创建的对象,静态方法当然意味着所有对象都访问相同的属性。

相反,据我所知,您希望实例组(并非所有实例)共享属性。

最简单的方法是创建一个共享对象,为组中的所有实例提供修改时间。

答案 2 :(得分:1)

正如其他评论者指出的那样,你不能简单地用基类来做这件事,因为这不是类层次结构的工作方式。你可以做的是创建另一个名为“GroupInfo”的类或类似的东西。使ModifiedTime成为该属性。

在所有其他类中,为GroupInfo添加属性。然后,每当你创建一本新书或其他什么时,作为构造函数的一部分传递对该书的GroupInfo的引用。

这样,组中的所有对象将共享一个GroupInfo,从而共享一个ModifiedTime。

答案 3 :(得分:0)

您可以使ModifiedTime为静态,这将导致它在MyBaseClass的所有派生实例之间共享。

public class MyBaseClass
{
  public static DateTime ModifiedTime{ get; set; }
}

答案 4 :(得分:0)

更新:更完整的示例;更好地解释方法

您的基类可以更好地描述为一个接口,因为您强制执行每个类实现一个公共属性,而不是进行通用计算或可以将学校,学生和书籍组合在一起的全面推广。

追求一个事件驱动的解决方案,您可以做一些事情,例如使用BindingList<T>,基本上List<T>类固醇。

不幸的是,您需要将漂亮的小{ get; set; }属性分解为完整字段,但最好的方法是每次修改属性以触发事件。受修改影响的每个后续对象都订阅了修改后的对象Modified事件。

public interface IChangeAware
{
    event EventHandler<EventArgs> OnChange;
    DateTime ModifiedTime { get; set; }
}

public class Student : IChangeAware
{
    public event EventHandler<EventArgs> OnChange;
    public DateTime ModifiedTime { get; set; }

    public string Name { get; set; }
    public School School
    {
        get { return School; }
        set 
        {
            School = value; 
            if (this.OnChange != null)
                this.OnChange(this, new EventArgs());
        }
    }

    public Student()
    {
        if (School != null)
            School.OnChange += MySchoolOnChange;
    }

    void MySchoolOnChange(object sender, EventArgs e)
    {
        ModifiedTime = DateTime.Now;
    }
}

public class School : IChangeAware
{
    public event EventHandler<EventArgs> OnChange;
    public DateTime ModifiedTime { get; set; }

    public string SchoolName { get; set; }
    public BindingList<Book> Books { get; set; }

    public School()
    {
        Books = new BindingList<Book>();
        Books.ListChanged += BooksListChanged;
    }

    void BooksListChanged(object sender, ListChangedEventArgs e)
    {
        ModifiedTime = DateTime.Now;
        OnChange(this, new EventArgs());
    }
}

public class Book
{
    public string BookName { get; set; }
}