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

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}");
输出结果:

C# 子类与父类互转注意项的更多相关文章
- 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- python子类调用父类的方法
python子类调用父类的方法 python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法.如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问, ...
- C#中子类调用父类的实现方法
这篇文章主要介绍了C#中子类调用父类的实现方法,通过实例逐步分析了类中初始化构造函数的执行顺序问题,有助于加深对C#面向对象程序设计的理解,需要的朋友可以参考下 本文实例讲述了C#中实现子类调 ...
- java 子类重写父类的方法应注意的问题
若想实现一个合格重写方法,而不是重载,那么必须同时满足下面的要求! A.重写规则之一: 重写方法不能比被重写方法限制有更严格的访问级别.(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法 ...
- C#中通过类来继承两个接口,父类实例化接口中的方法,子类继承父类,调用方法
实现了父类继承接口,父类实例化接口的方法,子类继承父类,子类调用父类的方法直接使用 代码如下: using System; using System.Collections.Generic; usin ...
- 子类重载父类的方法“parent:方法名”
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- 转:C++:从子类访问父类的私有函数
众所周知,c和c++的数组都是不安全的,因为无论c还是c++都不提供数组边界检查功能,这使得数组溢出成为可能.从某个意义上说,c和c++是一种缺少监督的语言,然而这也正是其魅力所在.c++给予程序员更 ...
- c++继承构造子类调用父类构造函数的问题及关于容器指针的问题及当容器里储存指针时,记得要手动释放
看下面的一个问题: class Person { private: string name; public: Person(const string& s=""){ nam ...
- c++子类和父类成员函数重名
子类和父类返回值参数相同,函数名相同,有virtual关键字,则由对象的类型决定调用哪个函数. 子类和父类只要函数名相同,没有virtual关键字,则子类的对象没有办法调用到父类的同名函数,父类的同名 ...
- PHP - 子类使用父类的构造函数
/* * 子类使用父类中的构造方法. */ //父类方法 class Person { //父类中的构造方法 function __construct(){ echo '这是父类中的构造方法!'; } ...
随机推荐
- Centos7部署rsync配合inotify进行系统文件实时备份
转载csdn: Centos7部署rsync配合inotify进行系统文件实时备份_xixixilalalahaha的博客-CSDN博客
- aspnetcore读取配置【源码分析】
总的逻辑 继承 IConfigurationSource 这个接口的子类是配置源 ,其中的build方法,创建并返回对应的ConfigurationProvider. 继承 IConfiguratio ...
- Yapi安装配置(CentOs)
环境要求 nodejs(7.6+) mongodb(2.6+) git 准备工作 清除yum命令缓存 sudo yum clean all 卸载低版本nodejs yum remove nodejs ...
- 深入理解Spring的Bean定义对象BeanDefinition-面试重点
Spring注解这篇文章中讲到了Spring的组件,组件加载到Spring容器中也就是Spring容器中的Bean对象,想要更深理解Spring中的Bean对象,那对这个BeanDefinition一 ...
- Django中models的字段
常见的field类型: 1.AutoField 自增字段,它是一个根据ID自增长的IntegerField字段,通常不用自己设置,如果没有设置主键,django会自动添加它为主键字段 2.CharFi ...
- vue3.0中ref动态绑定
// 自己使用 <div v-for="item in ['lisi','wanger']" :key="item"> <test :ref= ...
- ROS1 Qt5 CMake基本配置
############################################################################## # CMake ############# ...
- RestTemplate 请求
@Autowired private RestTemplate httpRestTemplate; String code= request.getParameter("code" ...
- html添加公共文件
html添加公共文件 记录添加公共头尾文件的方法 thymeleaf模板引擎 common.html index.html
- VMware-安装rpm包出现警告:tigervnc-1.1.0-24.el6.x86_64.
警告:tigervnc-1.1.0-24.el6.x86_64. 解决方法:rpm -ivh tigervnc-1.1.0-24.el6.x86_64.rpm --force --nodeps --n ...