C# 如何防止继承财产和子财产在域/目的方面发生干涉?
我正在使用C#.Net 4.7.2 情况: 假设我们有两个域: 在一个例子中,我们需要询问特定类型:project.Tasks。因为打电话的人不需要知道 该项目有子项目:IsScheduleAbe[]: 在另一个领域,我们需要知道事件的层次结构树来安排它们 现在,在这种设计中,当我想将任务添加到project.Tasks时,我必须将任务添加为可调度到project.Children。我们携带冗余信息,有点像 我尝试过的另一种方法是覆盖项目中孩子的getter:C# 如何防止继承财产和子财产在域/目的方面发生干涉?,c#,oop,C#,Oop,我正在使用C#.Net 4.7.2 情况: 假设我们有两个域: 在一个例子中,我们需要询问特定类型:project.Tasks。因为打电话的人不需要知道 该项目有子项目:IsScheduleAbe[]: 在另一个领域,我们需要知道事件的层次结构树来安排它们 现在,在这种设计中,当我想将任务添加到project.Tasks时,我必须将任务添加为可调度到project.Children。我们携带冗余信息,有点像 我尝试过的另一种方法是覆盖项目中孩子的getter: public override
public override List<ISchedulable> Children
{
get => Tasks.Cast<ISchedulable>().ToList();
}
公共覆盖列表子项
{
get=>Tasks.Cast().ToList();
}
但这意味着,我总是投下整个名单!我不能迭代列表,因为它在每次迭代时都会被“修改”
第三种方法是,我在需要的时候构建层次结构。我知道所有类型都继承自IsSchedulable,因此我可以构建层次结构并设置父级和子级。但是,在我们计算父/子对象之前,该对象的父/子对象将再次为null
我错过了什么?是否有人有一个将域分开的设计想法?Eric Evans在他的杰作《域驱动设计:软件的核心》中建议在一个域中绘制有界上下文。我想说的是,如果您已经知道一个概念(在本例中是可调度的、项目、任务和ToDo)用于不同的目的,那么您可能需要复制它们 无论如何,我似乎明白,一个项目不能有TODO或项目作为子项,一个任务不能有项目或TODO作为子项,TODO根本不能有子项。 让我们来看看这种方法,在这里我使用了复合模式和访问者模式:
public interface ISchedulable {
ISchedulable Parent {get;set;}
IEnumerable<ISchedulable> Children {get;} //this collection is readonly
DateTime Start {get; set; }
DateTime End {get; set; }
T AcceptVisitor<T>(ISchedulableVisitor<T> visitor);
}
public interface ISchedulableVisitor<T> {
T Visit(Project p);
T Visit(Task t);
T Visit(ToDo td);
}
public abstract class SchedulableBase : ISchedulable {
public ISchedulable Parent {get;set;}
public abstract IEnumerable<ISchedulable> Children {get;} //this collection is readonly
public DateTime Start {get; set; }
public DateTime End {get; set; }
public abstract T AcceptVisitor<T>(ISchedulableVisitor<T> visitor);
}
public class Project : SchedulableBase {
public override IEnumerable<ISchedulable> Children => Tasks.Cast<ISchedulable>();
private readonly List<Task> _tasks = new List<Task>();
public IEnumerable<Task> Tasks => _tasks;
public void AddTask(Task t) {
t.Parent = this;
_tasks.Add(t);
}
public string Description {get;set;}
public override T AcceptVisitor<T>(ISchedulableVisitor<T> visitor) => visitor.Visit(this);
}
public class Task : SchedulableBase {
public override IEnumerable<ISchedulable> Children => ToDos.Cast<ISchedulable>();
private readonly List<ToDo> _todos = new List<ToDo>();
public IEnumerable<ToDo> ToDos => _todos;
public void AddToDo(ToDo t) {
t.Parent = this;
_todos.Add(t);
}
public Employee Head {get;set;}
public override T AcceptVisitor<T>(ISchedulableVisitor<T> visitor) => visitor.Visit(this);
}
public class ToDo : SchedulableBase {
public override IEnumerable<ISchedulable> Children => Enumerable.Empty<ISchedulable>();
public object Whatever {get;set;}
public override T AcceptVisitor<T>(ISchedulableVisitor<T> visitor) => visitor.Visit(this);
}
你没有一个基类继承了子类吗?因此,您可以在继承类的基类和层次结构树中放入最少的信息。@jdweng:基类为谁?继承类(子类)的属性多于基类(父类)。因此,您希望父对象拥有有限数量的属性,而子对象拥有详细的属性。感谢您为编写代码所做的努力。我喜欢复合模式的想法,我现在正在实施。直到现在我还没有弄坏什么东西,所以看起来不错=)
public class ToDosCounter : ISchedulableVisitor<int> {
public int Visit(Project p) {
int ris = 0;
foreach (Task t in p.Tasks) {
ris += t.AcceptVisitor(this);
}
return ris;
}
public int Visit(Task t) {
int ris = 0;
foreach(ToDo td in t.ToDos) {
ris+=td.AcceptVisitor(this);
}
return ris;
}
public int Visit(ToDo td) {
return 1;
}
}
public void DoLogic(ISchedulable s) {
var numberOfTodos = s.AcceptVisitor(new ToDoCounter());
///
}