2011-11-06 72 views
4

在管理的职业培训制度,我有一个CourseBase抽象类,这是我使用赞成ICourse接口的决定,因为我宁愿避免重复从假想派生的所有类的实现代码,基础Course实体。每个课程都有一个列表,如果科目与SubjectBase抽象类定义任何主题。所以,我有我应该如何抽象另一个对象拥有的对象的集合?

public abstract class CourseBase : BaseObject 
{ 
    public IEnumerable<SubjectBase> Subjects 
    { 
     get { return new List<SubjectBase>(); } 
    } 
} 

public abstract class SubjectBase 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public int ValidityPeriod { get; set; } 
} 

现在,我想补充一个具体的类,LocalCourse,其中包含LocalCourseSubject对象的集合,而是因为我没有使用一个接口,用于CourseBase,我失去了协方差,我需要隐藏抽象基的Subjects财产与我的新:

public class LocalCourse: CourseBase 
{ 
    public IEnumerable<LocalCourseSubject> Subjects 
    { 
     get { throw new NotImplementedException(); } 
    } 
} 

我敢肯定,我错过了从一个角度OO点东西在这里很明显,但唯一的解决方案,我可以看到的是:

  1. 完全忽略抽象基础中的主题,并且只将特定类型的集合属性添加到派生类中。
  2. 在抽象基础和具体类中实现一个接口,如ISubjectCollectionOwner

请原谅我的朦胧,这已经有一段时间了,因为我有幸遇到过这样的设计问题。

+0

您正在使用哪种版本的C#和.NET?它在通用方差方面有所不同。顺便问一下,你真的需要所有的抽象吗?你会有什么不同类型的课程和科目? –

+1

不是SubjectBase的要点,因此您可以使用多态性来处理所有相同的主题。你不能只是摆脱你的主体覆盖,并使用CourseBase主题集合呢? –

+0

@Jon,v4。我的'规范'是为了迎合'各种各样的事情',所以我只是在早期获得足够的抽象以支持基本实体的广泛扩展而赌博。 – ProfK

回答

1

抽象它不能你只是这样做:

public abstract class CourseBase<T> where T : SubjectBase 
{ 
    public virtual IEnumerable<T> Subjects 
    { 
     get { return new List<T>(); } 
    } 
} 

public abstract class SubjectBase 
{ 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public int ValidityPeriod { get; set; } 
} 

public class LocalCourse : CourseBase<LocalCourseSubject> 
{ 
    public override IEnumerable<LocalCourseSubject> Subjects 
    { 
     get { throw new NotImplementedException(); } 
    } 
} 

我认为这将实现你的短期目标,无论如何,假设的一般模式是,每个CourseBase继承人将具有相同类型SubjectBase传承的集合。但是,如果是这样的话,这看起来像是一个平行的继承层次结构,有时可能是代码味道(并不是说它一定是 - 我不知道你正在建模的域的所有细节)。

+0

这似乎是我所建模的域名的所有者甚至不清楚细节,但是谢谢,这是一个整洁的候选人。 – ProfK

+0

很高兴,如果它以某种方式帮助。 :) –

2

为什么不引入一个通用的接口来抽象课程?很抱歉,如果我错过了一些明显的

public interface ICourse<TSubject> 
{ 
    IEnumerable<TSubject> Subjects { get; } 
} 

public abstract class CourseBase<TSubject> 
    : BaseObject, 
    ICourse<TSubject> 
{ 
    public IEnumerable<TSubject> Subjects 
    { 
     get { return new List<TSubject>(); } 
    } 
} 

public class LocalCourse 
    : CourseBase<LocalCourseSubject> 
{ 
} 

如果主题当然是实体的重要组成部分,你应该保持它都ICourse和CourseBase内为好,否则我会suggects通过ISubjectAware接口

+0

我认为这是一个坏主意。 @上面的科斯曼已经有了正确的想法。使用这样的泛型会破坏多态性,并且您将无法以通用方式处理主题集合。 – xanadont

+0

我不知道我说得没错 - '你不能用普通的方式处理主题的集合',你能举个例子吗? – sll

+1

如果这是。-4.0之前的版本,我将能够给你一个例子。但我现在刚刚接受了协变研究并做了类似“IEnumerable objs = new List ();”是可能的。这很有趣,可能会改变我未来的对象模型设计。对不起,噪音。 – xanadont

相关问题