昨晚在处理父类与子类相互转换时,想把父类转换子类对象,发现编译不通过 ,类定义如下:

 public interface IPeople
{
int Age {
get;
set;
} string Name {
get;
set;
}
} public class People : IPeople
{
public int Age { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
} public class Student : People
{ }

测试代码:

 IPeople p = new People();
Student stu = (Student)p;

这里, People 继承 IPeople , Student 继承 People , 即 Student 是 People 子类 , 先创建父类对象,原后强转子类,运行报错:

如上,换个方式, Student , People 均继承 IPeople , 试试看:

 public class People : IPeople
{
public int Age { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
} public class Student : IPeople
{
public int Age { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}

一样报错:

这里 Student 与 People 均继承  IPeople , 仍报错 , Student 与 People 不能互相转换,但二者可以转成 IPeople ,做为通用方法传参使用。

如:

  static void Print(IPeople p) {
Console.WriteLine($"age:{p.Age}");
Console.WriteLine($"name:{p.Name}");
}

另一种合法转换,如子类转父类是充许的,在如上第一示例基础上,运行如下测试代码,一切正常:

  IPeople p = new Student();
Student stu = (Student)p;

这里可以推测 在内存中 创建(New Student())  对象,本质上就是 Student , 同理 创建 (New People()) 对象,本质上就是 People , 之所以子类能够转换父类,只是逻辑层转换(内存结构不变),因为子类继承父类所有功能属性。逻辑层面,子类转成父类后,能够像调用父类方法一样调用子类。

由于父类无法转换子类,因此只能自个写一些转换逻辑,比如 在子类构造中 传入父类对象,显示将父类属性copy 至子类,考虑到 copy 繁琐 , 可借助反射属性方式 自动同步。

  public class People : IPeople
{
public int Age {
get;
set;
}
public string Name {
get;
set;
}
} public class Student : People
{
public Student() { } public Student(People peo) {
SynchronizationProperties(peo, this);
} void SynchronizationProperties(object src , object des) {
Type srcType = src.GetType();
object val;
foreach (var item in srcType.GetProperties())
{
val = item.GetValue(src);
item.SetValue(des, val ); }
}
}

调用代码:

 //创建父类对象
People p = new People() { Age = 18, Name = "张三" }; //将父类对象传入子类,Copy 公共属性
Student stu = new Student(p); Console.WriteLine($"Name:{stu.Name} , Age:{stu.Age}");

输出结果:

最新文章

  1. Mysql学习笔记(附一)
  2. WebAPi的可视化输出模式(RabbitMQ、消息补偿相关)——所有webapi似乎都缺失的一个功能
  3. Apache开启状态查看页面(原创贴-转载请注明出处)
  4. re模块汇总
  5. 方法的覆盖(override)、重载(overload)和重写(overwrite)
  6. Oracle学习系列1-7
  7. jquery层居中,点击小图查看大图,弹出层居中代码
  8. android115 自定义控件
  9. sql性能优化总结(转)
  10. leetcode_question_112 Path Sum
  11. EF连接MySQL数据Web.Config配置
  12. LeetCode & Q14-Longest Common Prefix-Easy
  13. eclispe 导入android或者java项目出现中文乱码
  14. 控制WinForm中Tab键的跳转
  15. NOIP2017滚粗记【下】
  16. AP_标准预付款核销基本操作(流程)
  17. js判断字符串str是否包含字符串substr
  18. 手机SLAM开发
  19. 模糊搜索:concat各种函数详解、like操作符、通配符
  20. EasyUI学习笔记(二)—— Layout

热门文章

  1. php pdo如何查询记录条数
  2. .Net Core IIS部署以及问题总结
  3. 慧销平台ThreadPoolExecutor内存泄漏分析
  4. oculus 安装其他盘方法
  5. 死磕rmi之 RegistryImpl
  6. WebForm发布IIS后,报错无谓词错误
  7. Android FragmentTabHost底部选项卡实现
  8. Windows Python2.7环境 安装paramiko模块(转)
  9. java开发细节
  10. java SE01