iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#实现子类与父类的相互转换
  • 1147
分享到

C#实现子类与父类的相互转换

2024-04-02 19:04:59 1147人浏览 安东尼
摘要

目录子类与父类的相互转换例一例二子类父类之间相互转换的问题父类:动物类(Animal)子类:狗类(Dog)子类与父类的相互转换 1.父类不能直接强制转换成子类 2.子类可以强制转换成

子类与父类的相互转换

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

结果:

在这里插入图片描述

更多有关反射的内容可以参考官方文档

到这里结论应该清楚了

  • 子类可以转换为父类,并且子类中的扩展属性会被父类“隐性”保留,但不可访问(编译出错),以便父类重新转换为子类。
  • 父类不可转为子类,这里倒是很好理解,毕竟多变少可以,少变多就不行了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: C#实现子类与父类的相互转换

本文链接: https://www.lsjlt.com/news/149342.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c语言怎么计算字符串长度
    在C语言中,可以使用内置的strlen()函数来计算字符串的长度。该函数位于string.h头文件中。以下是一个示例代码: #inc...
    99+
    2024-05-14
    c语言
  • c语言怎么判断三个数的大小
    可以通过比较三个数之间的大小关系来判断它们的大小。以下是一个示例代码: #include <stdio.h> int ...
    99+
    2024-05-14
    c语言
  • c++排序函数sort怎么使用
    在C++中,使用sort函数对容器中的元素进行排序,可以按照默认的升序排列,也可以自定义排序规则。 下面是一个简单的例子,对一个ve...
    99+
    2024-05-14
    c++
  • c++中string的compare函数怎么使用
    在C++中,可以使用string的compare函数来比较两个string对象的大小。该函数的原型如下: int compare(c...
    99+
    2024-05-14
    c++
  • c++中string的compare函数有什么用
    c++中string的compare函数用于比较两个字符串的大小关系。该函数返回一个整数值,表示两个字符串的比较结果。 具体来说,如...
    99+
    2024-05-14
    c++
  • c++中print函数的功能有哪些
    在C++中,通常使用std::cout来进行输出操作,而不是使用print函数。std::cout是C++标准库中的一个输出流对象,...
    99+
    2024-05-14
    c++
  • c语言数据结构怎么使用
    在C语言中,数据结构可以通过定义结构体来实现。以下是一些常见的数据结构的使用方法示例: 链表: #include <std...
    99+
    2024-05-14
    c语言
  • c++中print函数的用法是什么
    在C++中没有内置的print函数,但可以使用cout来输出内容到控制台。cout是C++标准库中的一个输出流对象,可以使用<...
    99+
    2024-05-14
    c++
  • c++中concept的用法是什么
    在C++20中,Concept是一种新的语言特性,用于定义类型要求和约束。Concept可以被用来约束函数模板、类模板和普通函数的参...
    99+
    2024-05-14
    c++
  • c++中concept的作用是什么
    在C++中,concept的作用是定义一种通用的约束,用于限制模板参数的类型范围。通过使用concept,可以在编译时对模板参数进行...
    99+
    2024-05-14
    c++
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作