在派生类中添加属性

时间:2011-03-24 16:04:18

标签: c# design-patterns

所以我试图编写接口而不是实现。所以我有一个工厂,它返回一个派生自Employee的对象。因此,这些对象可能类似于Developer:Employee,Secretary:Employee等。

所以我将所有共享属性(如FirstName,LastName,Email等)放在基类(Employee)中。

我应该将每种类型的所有属性都放在那种类型中。因此,开发人员会在其中拥有一些属性,如Skills,ProgrammingLanguages等,但除非我使用具体类型的Developer,否则我将无法从Employee对象访问这些属性。

e.g。

Employee employee = new EmployeeFactory.CreateEmployee(EmployeeType.Developer);
employee.ProgrammingLanguages = "C#, Java, C++"; <-- compile error

最好的方法是什么?反射...?

5 个答案:

答案 0 :(得分:4)

如果您要明确说明要使用哪种类型的员工,为什么要打扰工厂?

相反,你可以写:

Developer dev = new Developer();
dev.ProgrammingLanguages = "C#, Java, C++"; // compiles fine

稍后,您仍然可以将“开发人员”添加到员工列表中,即:

IList<Employee> theEmployees = GetEmployees();
theEmployees.Add(dev); // This is fine, since Developer is an Employee...

答案 1 :(得分:2)

为什么不使用泛型并具有类似

的内容
T EmployeeFactory.CreateEmployee<T>() 
{
     return new T();
}

并称之为

var dev = EmployeeFactory.CreateEmployee<Developer>();

这样你最终会得到一个打字的开发者。

答案 2 :(得分:1)

在您的代码中,显然当您尝试employee.ProgrammingLanguages时,您知道employee属于Developer类型。所以你可以投入到那个:

Developer dev = new (Developer)EmployeeFactory.CreateEmployee(EmployeeType.Developer);
dev.ProgrammingLanguages = "C#, Java, C++";

或者更多:

Developer dev = new Developer(); // If you don't really need the factory.
dev.ProgrammingLanguages = "C#, Java, C++";

在您不知道是否可以执行此操作的情况下,您可以使用isas进行测试。

将事物保持在他们有意义的水平上来处理它们。显然,谈论可能没有编程的人的编程语言是没有意义的,因此可以在层次结构的Developer级别工作。处理假期和薪水的代码应该对所有员工都相同,或者至少通过可以覆盖的公共接口工作,因此它可以在层次结构的Employee级别工作。

答案 3 :(得分:0)

在我看来,至少在这种特定情况下,你不应该使用基类型。

您正在使用特定于Developer而非通用Employee的内容,因此您将失去使用基本类型的好处。在这种情况下,只需创建一个新的开发人员:

Developer developer = new Developer();
developer.ProgrammingLanguages = "C#, Java, C++";

话虽这么说,你总是可以尝试演员回到更具体的类型:

Employee employee = new EmployeeFactory.CreateEmployee(EmployeeType.Developer);

Developer developer = employee as Developer;
if(developer != null) developer.ProgrammingLanguages = "C#, Java, C++";

答案 4 :(得分:0)

在这种情况下,我建议使用最简单的解决方案。为每个员工类型创建一个方法,如下所示:

public Developer CreateDeveloper();
public Secretary CreateSecretary();

为什么这个“丑陋”的解决方案?因为您需要知道客户端代码中的类型。那么为什么要使泛型/反射变得复杂呢?简朴是神圣的。