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

輸出結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM