• 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
        {
          
        }
    View Code

    测试代码:

     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(); }
        }
    View Code

    一样报错:

     这里 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 );
              
                }
            }
        }
    View Code

    调用代码:

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

    输出结果:

  • 相关阅读:
    需要登陆网站后才能获取数据的页面爬取
    PTA中提交Python3程序的一些套路
    PAT 甲级 1014 Waiting in Line (30 分)(queue的使用,模拟题,有个大坑)
    PAT 甲级 1013 Battle Over Cities (25 分)(图的遍历,统计强连通分量个数,bfs,一遍就ac啦)
    PAT 甲级 1012 The Best Rank (25 分)(结构体排序)
    anconda + python 3.6安装(以前的anconda,anaconda和python版本对应关系)
    数学建模python matlab 编程(喷泉模拟)
    数学建模python matlab 编程(疾病传播模型)
    scikit-learn机器学习(四)使用决策树做分类,并画出决策树,随机森林对比
    scikit-learn机器学习(四)使用决策树做分类
  • 原文地址:https://www.cnblogs.com/howtrace/p/13197486.html
Copyright © 2020-2023  润新知