所以我试图编写接口而不是实现。所以我有一个工厂,它返回一个派生自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
最好的方法是什么?反射...?
答案 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++";
在您不知道是否可以执行此操作的情况下,您可以使用is
或as
进行测试。
将事物保持在他们有意义的水平上来处理它们。显然,谈论可能没有编程的人的编程语言是没有意义的,因此可以在层次结构的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();
为什么这个“丑陋”的解决方案?因为您需要知道客户端代码中的类型。那么为什么要使泛型/反射变得复杂呢?简朴是神圣的。