日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C#實現子類與父類的相互轉換_C#教程

作者:不曾設想的道路 ? 更新時間: 2022-07-17 編程語言

子類與父類的相互轉換

1.父類不能直接強制轉換成子類

2.子類可以強制轉換成父類,但是在父類中只能取父類的字段與方法因此在一個父類對應多個子類的時候,不知道具體是哪個子類的時候,就可以先聲明一個父類的類型。(如例1)

3.由1,2知,父類不能直接強制轉換成子類,但是可以通過間接的方法進行轉換,例1中有所體現:將子類轉換成父類,然后再把父類轉換成子類,如例2。

特別說明:雖然可以通過間接方式將父類轉成子類,但實際用處不大,因為需要一個臨時的子類來進行轉換,因為其實可以直接在子類直接轉換,所以實際用處不大。

(下例只適用于從棧制到堆的行為,即裝箱拆箱)

例一

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
namespace testApplication  
{  
 public class Parent  
    {  
        public int a=0;  
    }  
    public class Son:Parent  
    {  
        public int b=0;  
        public int run()  
        {  
            return a + b;  
        }  
    }  
    public class Son2 : Parent  
    {  
        public string c = "Son2";  
        public int run()  
        {  
            return a;  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            //不知道具體是哪個子類,因此先用父類來聲明  
            List<Parent> sL = new List<Parent>();  
            Son cs1 = new Son(); cs1.b = -1;  
            Son cs2 = new Son(); cs2.b = -2;  
            sL.Add(cs1);  //子類可以強制轉換成父類,即裝箱 
            sL.Add(cs2);  
            for (int i = 0; i < 2;i++ )  
            {  
                //這里需要把父類再強制轉換成子類(因為是裝箱而來的父類,可以對其進行拆箱成子類)  
                //取出子類中的字段,即拆箱  
                Console.WriteLine(((Son)sL[i]).b);  
            }  
            Console.ReadLine();  
        }  
    }  
}  

例二

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
namespace testApplication  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Parent pa = new Parent();  
            pa.a=9;  
            //設置一個臨時的子類  
            Son tmpt = new Son();  
            tmpt.a = 9;  
            //進行裝箱  
            pa = (Parent)tmpt;  
            //進行拆箱  
            Son cson = (Son)pa;  
            Console.WriteLine(cson.a);  
            Console.ReadLine();  
        }  
    }  
    public class Parent  
    {  
        public int a=0;  
    }  
    public class Son:Parent  
    {  
        public int b=0;  
        public int run()  
        {  
            return a + b;  
        }  
    }  
    public class Son2 : Parent  
    {  
        public string c = "Son2";  
        public int run()  
        {  
            return a;  
        }  
    }  
}  

子類父類之間相互轉換的問題

為了方便演示,這里一共有兩個簡單的類

父類:動物類(Animal)

/// <summary>
/// 動物類-父類
/// </summary>
public class Animal
{
    /// <summary>
    /// 腳
    /// </summary>
    public string Foot { get; set; }
    /// <summary>
    /// 頭
    /// </summary>
    public string Head { get; set; }
}

子類:狗類(Dog)

/// <summary>
/// 狗類-繼承動物類
/// </summary>
public class Dog : Animal
{
    /// <summary>
    /// 尾巴
    /// </summary>
    public string Tail { get; set; }
    /// <summary>
    /// 構造函數
    /// </summary>
    public Dog()
    {
        Head = "狗頭";
        Foot = "狗腿";
        Tail = "狗尾巴";
    }
}

第一步:如果我們將Dog類轉換為Animal類

Dog dog = new Dog();
//轉換為動物類---子類轉換為父類
Animal animal = dog as Animal;

這個按照我們一貫的想法,應該就是舍去子類的擴展屬性(這里是Tail),只保留父類中的屬性(Foot,Head)。那么結果轉換后的Animal類應該這樣的

在這里插入圖片描述

第二步:而如果我們繼續把這個對象重新轉換為Dog類 Dog dog2 = animal as Dog; Dog類應該是這樣的

在這里插入圖片描述

但是事實上,在第一步把Dog轉換為Animal時,Animal沒有把Tail這個字段拋去,如下圖

在這里插入圖片描述

但是,在VS的智能提示中我們并不能訪問Tail屬性,直接使用編譯也會報錯

在這里插入圖片描述

而且從上面的結果中,我們也能猜出第二步的實際結果,Dog類中Tail并不是NULL

在這里插入圖片描述

第三步:試試父類轉換為子類

在這里插入圖片描述

很明顯,父類并不能轉換成子類,雖然編譯可以通過,但是運行時會拋出System.InvalidCastException異常,當然這里使用as關鍵詞可以避免這一異常,結果返回NULL

那么父類怎么轉換成子類呢?對于一些相對簡單的類,我們可以通過遍歷的方式逐個賦值

Animal animal = new Animal
{
    Foot = "腳",
    Head = "頭"
};
Dog dog = new Dog
{
    Foot = animal.Foot,
    Head = animal.Head,
};

如果屬性多的時候,使用這種方法就麻煩了,這時可以使用反射遍歷屬性來設置對應的值

Animal animal = new Animal
{
    Foot = "腳",
    Head = "頭"
};
Dog dog = new Dog();
//遍歷Animal類的公共屬性
foreach (PropertyInfo item in typeof(Animal).GetProperties())
{
    item.SetValue(dog, item.GetValue(animal));
}

結果:

在這里插入圖片描述

更多有關反射的內容可以參考官方文檔

到這里結論應該清楚了

  • 子類可以轉換為父類,并且子類中的擴展屬性會被父類“隱性”保留,但不可訪問(編譯出錯),以便父類重新轉換為子類。
  • 父類不可轉為子類,這里倒是很好理解,畢竟多變少可以,少變多就不行了。

原文鏈接:https://blog.csdn.net/a1256242238/article/details/72843141

欄目分類
最近更新