【发布时间】:2018-03-01 14:44:24
【问题描述】:
我有一个 Employee 类,以及从它派生的 FulltimeEmployee 和 ParttimeEmployee 类。我在 Employee 类上应用了一个 [KnownType] 属性。 Employee 类用作 WCF 服务的 DataContract。
我有一个 MVC 应用程序作为 WCF 客户端。我根据需要成功检索了 FulltimeEmployee 或 ParttimeEmployee,并将其用作视图的模型。该模型是基本类型 Employee。层次结构被保留:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("dotnet-svcutil", "0.5.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="FullTimeEmployee", Namespace="http://schemas.datacontract.org/2004/07/EmployeeService")]
public partial class FullTimeEmployee : EmployeeService.Employee
{
...
但是当我尝试保存一个新员工时,我得到了一个异常:
InvalidCastException:无法转换类型的对象 'EmployeeService.Employee' 输入'EmployeeService.PartTimeEmployee'。
代码如下:
Employee emp = null;
if(employee.Type == EmployeeType.FullTimeEmployee)
{
...
}
else
{
emp = new PartTimeEmployee
{
Name = employee.Name,
Gender = employee.Gender,
Type = employee.Type,
DateOfBirth = employee.DateOfBirth,
HourlyPay = ((PartTimeEmployee)employee).HourlyPay,
HoursWorked = ((PartTimeEmployee)employee).HoursWorked
};
为什么会这样?
【问题讨论】:
-
“当我尝试保存新员工时”,我没有看到任何与保存相关的内容。它到底在哪里失败了?
-
通常当使用这种结构时(检查 type == x 等)表明设计不好
-
这里没有关于类及其层次结构的足够信息,而且您提到的实际演员表代码甚至都不存在。如果
Employee不是一个抽象类,并且你有一个这种类型的实际实例化对象,那么显然你不能将它转换为子类型。因为不是。 -
您说MVC中的视图模型是基本类型
Employee。这意味着视图会将Employee的实例提交回控制器。那时您没有任何关于Employee子类型的信息,因此无法将其转换为子类型。这是基本的 OOP 基础。 -
使用这种方法基本上会丢失子类型的属性。因此,您需要为每个子类型作为模型有不同的视图和发布操作。