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}");

输出结果:

 

posted on 2020-06-27 10:15  千浔  阅读(9838)  评论(0编辑  收藏  举报