C# 子类与父类互转注意项
2024-09-07 16:48:03
昨晚在处理父类与子类相互转换时,想把父类转换子类对象,发现编译不通过 ,类定义如下:
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}");
输出结果:
最新文章
- Mysql学习笔记(附一)
- WebAPi的可视化输出模式(RabbitMQ、消息补偿相关)——所有webapi似乎都缺失的一个功能
- Apache开启状态查看页面(原创贴-转载请注明出处)
- re模块汇总
- 方法的覆盖(override)、重载(overload)和重写(overwrite)
- Oracle学习系列1-7
- jquery层居中,点击小图查看大图,弹出层居中代码
- android115 自定义控件
- sql性能优化总结(转)
- leetcode_question_112 Path Sum
- EF连接MySQL数据Web.Config配置
- LeetCode &; Q14-Longest Common Prefix-Easy
- eclispe 导入android或者java项目出现中文乱码
- 控制WinForm中Tab键的跳转
- NOIP2017滚粗记【下】
- AP_标准预付款核销基本操作(流程)
- js判断字符串str是否包含字符串substr
- 手机SLAM开发
- 模糊搜索:concat各种函数详解、like操作符、通配符
- EasyUI学习笔记(二)—— Layout