昨晚在處理父類與子類相互轉換時,想把父類轉換子類對象,發現編譯不通過 ,類定義如下:

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}");
輸出結果: