在派生类中添加属性

问题描述:

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

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

而且我应该把每种类型特有的所有属性放在这种类型中。因此,Developer会拥有像Skills,ProgrammingLanguages等一些属性,但是除非我使用具体类型的Developer,否则我将无法从Employee对象访问这些属性。

例如

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

什么是最好的方式去做这件事?反射...?

+0

我觉得在这种情况下,你只需要在作业前备份。 – asawyer 2011-03-24 16:06:42

+0

在这种情况下,对基类进行编码没有意义,因为您明确地从派生类访问属性 – 2011-03-24 16:09:59

+0

如果您决定采用反思方式,则可能需要在.NET 4中使用动态关键字这会使代码看起来更清晰。 – 2011-03-24 16:14:03

为什么不使用泛型和有类似

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

,并调用它像

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

这样,你最终会得到一个类型化的开发。

+0

这会要求在编译时知道'Employee'的类型,而这对于当前代码是不必要的。 – Jon 2011-03-24 16:08:53

+0

如果该类型是可变的,则该代码将不起作用,但是当前代码指出该代码或多或少硬编码(作为枚举)。 – 2011-03-24 16:12:23

+0

我喜欢这个。但是,我怎样才能向构造函数发送一个参数?公共静态T EmployeeFactory ()其中T:员工 {字符串someParam =“”; 返回新的T(someParam); } – Joe 2011-03-24 16:24:15

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

相反,你可以只写:

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... 
+0

我明白了你的观点,但我确实喜欢工厂,因为那样我就可以像db连接字符串一样传递一些初始化给每个派生类,并且获得初始化参数的所有逻辑都将处于一个位置。尽管我想我可以将它移到基类中......不确定实际的好处和缺点。 – Joe 2011-03-24 16:30:08

+0

@Joe:是的 - 它可以很容易地在基类中,并传递给构造函数。除非你想要“隐藏”真正的课程,否则真的没什么优势。 – 2011-03-24 16:31:32

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

您正在使用特定于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++"; 

在代码中,明确当您尝试做employee.ProgrammingLanguages你知道employeeDeveloper类型。所以,你可以只投至:

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级别上工作。

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

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

为什么这个“丑陋的”解决方案?因为您需要以任何方式了解客户端代码中的类型。那么为什么要使泛型/反射复杂化呢?简单是神圣的。