c# - 正确更新子类型
问题描述
我正在尝试编写Update
将更新给定对象的属性的方法。为了让这个例子简单想象,我有这些类:
public class Person
{
public string Name;
public virtual void Update(Person person)
{
this.Name= person.Name;
}
}
public class Employee : Person
{
public string Id;
public override void Update(Person person)
{
base.Update(person);
var employee = person as Employee;
this.Id= employee.Id;
}
}
public class Manager: Employee
{
public string Title;
public override void Update(Person person)
{
base.Update(person);
var manager = person as Manager;
this.Title = manager.Title;
}
}
这只是一个转储示例,要说:我有很深的继承。在每个级别中,都有更多属性添加到子类型中。我正在尝试update
为所有子类型编写一个方法。
铸造内部Update
方法似乎不是一个好主意。我正在考虑使用通用方法。如果我有 2 级继承就好了。但是如果继承太深,我需要将所有子类型通用到最后一个孩子。
有更好的方法Update
吗?
解决方案
Update
您可以通过为子类型添加重载来避免强制转换,如下所示:
public class Person
{
public string Name;
public virtual void Update(Person person)
{
this.Name = person.Name;
}
}
public class Employee : Person
{
public string Id;
public virtual void Update(Employee employee)
{
base.Update(employee);
this.Id = employee.Id;
}
}
public class Manager: Employee
{
public string Title;
public void Update(Manager manager)
{
base.Update(manager);
this.Title = manager.Title;
}
}
一个可能的缺点是,这会保留基本版本并在所有级别都可用,所以现在您可以这样做:
var p = new Person { ... }
var m = new Manager { ... }
m.Update(p); // Updates only the Name
如果您想防止这种情况发生,那么您必须Update(<base type> x)
在每个子类中重写并抛出某种(运行时)异常。
推荐阅读
- typescript - 如何在 Typescript 中向导入的库模块添加新方法/属性?
- flutter - 如何在 ci 上保存颤振缓存以节省 circleci 的时间
- javascript - 如何使用 javascript 更改脚本标签的内容?
- arrays - 为什么未指定大小的数组后面不能跟结构中的另一个字段?
- laravel - Laravel 路线未定义,但已明确定义
- string - 在 vb.net 代码中搜索和替换部分字符串
- php - Laravel如何让每个用户只获得一条记录
- python - 使用 np.piecewise 对大数据集进行分段线性回归
- vba - 下标超出范围 VBA 打印
- visual-studio-code - OpenJDK11 和 java 1.8 编译器