当前位置: 首页 > news >正文

C# 转换(引用转换)

引用转换

我们已经知道引用类型对象由内存中的两部分组成:引用和数据。

  • 由引用保存的那部分信息是它指向的数据类型。

  • 引用转换接受源引用并返回一个指向堆中同一位置的引用,但是把引用“标记”为其他
    类型。
    例如,如下代码给出了两个引用变量:myVar1和myVar2,它们指向内存中的相同对象。代
    码如图17-17所示。

  • 对于myvarl,它引用的对象看上去是3类型的对象一一一其实就是。

  • 对于myVar2,同样的对象看上去像A类型的对象。

    • 即使它实际指向B类型的对象,它也看不到B扩展A的部分,因此看不到Field2。
    • 第二个WriteLine语句因此会产生编译错误。
      注意,“转换"不会改变myVar1。
class A {public int Field1;}class B:A {public int Field2;}class Program
{static void Main(){B myVar1=new B();//作为A类的引用返回myVar1的引用A myVar2=(A)myVar1;Console.WriteLine($"{myVar2.Field1}"); //正确COnsole.WriteLine($"{mVar2.Field2}"); // 编译错误 Field2对于myVar2不可见}
}

引用转换返回与对象关联的不同类型

隐式引用转换

与语言为我们自动实现的隐式数字转换类似,还有隐式引用转换,如图17-18所示。

  • 所有引用类型可以被隐式转换为object类型。
  • 任何接口可以隐式转换为它继承的接口。
  • 类可以隐式转换为:
    • 它继承链中的任何类;
    • 它实现的任何接口。

类和接口的隐式转换

委托可以隐式转换成图17-19所示的.NETBCL类和接口。Arrays数组(其中的元素是Ts类
型)可以隐式转换成:

  • 图17-19所示的.NET BCL类和接口;
  • 另一个数组ArrayT,其中的元素是Tt类型(如果满足下面的所有条件)。
    • 两个数组维度的一样。
    • 元素类型Ts和Tt都是引用类型,不是值类型。
    • 在类型Ts和Tt中存在隐式转换。

委托和数组的隐式转换

显式引用转换

显式引用转换是从一个普通类型到一个更精确类型的引用转换。

  • 显式转换包括:
    • 从object到任何引用类型的转换;
    • 从基类到派生自它的类的转换。
  • 倒转图17-18和图17-19的箭头方向,可以演示显式引用转换。
    如果转换的类型不受限制,我们很容易尝试引用在内存中实际并不存在的类成员。然而,编
    译器确实允许这样的转换。但如果系统在运行时遇到它们,则会抛出异常。

例如,图17-20中的代码将基类A的引用转换到它的派生类B,并且把它赋值给变量myVar2。

  • 如果myVar2尝试访问Field2,它会尝试访问对象中"B部分"的字段(它不在内存中),
    这会导致内存错误。
  • 运行时会捕获到这种不正确的强制转换并且抛出InvalidCastException异常。然而,注
    意,它不会导致编译错误。

|无效的转换抛出运行时异常

有效显式引用转换

在运行时能成功进行(也就是不抛出InvalidCastException异常)的显式转换有3种情况。
第一种情况:显式转换是没有必要的。也就是说,语言已经为我们进行了隐式转换。例如,
在下面的代码中,显式转换是没有必要的,因为从派生类到基类的转换总是隐式转换。

class A {public int Field1;}
class B:A{public int Field2;}
...
B myVar1=new B();
A myVar2=(A)myVar2;  //不必转换,因为A是B的基类

第二种情况:源引用是null。例如,在下面的代码中,即使转换基类的引用到派生类的引用
通常是不安全的,但是由于源引用是null,这种转换还是允许的。

class A {public int Field1;}
class B:A{public int Field2;}
...
A myVar1=null;
B myVar2=(B)myVar1;  //允许转换,因为myVar1为空

第三种情况:由源引用指向的实际数据可以安全地进行隐式转换。如下代码给出了一个示例,
图17-21演示了这段代码。

  • 第二行中的隐式转换使myVar2看上去像指向A类型的数据,其实它指向的是B类型的数
    据对象。
  • 第三行中的显式转换把基类引用强制转换为它的派生类的引用。这通会产生异常。然
    而,在这种情况下,指向的对象实际就是B类型的数据项。
class A {public int Field1;}
class B:A{public int Field2;}...
B myVar1=new B();
A myVar2=myVar1;     //将myVar1隐式转换为A类型
B myVar2=(B)myVar2;  //该转换是允许的,因为数据是B类型

强制转换到安全类型

http://www.xdnf.cn/news/1140661.html

相关文章:

  • 超简单linux上部署Apache
  • React + Mermaid 图表渲染消失问题剖析及 4 种代码级修复方案
  • B 站关键词排名提高之账号互助术:矩阵助攻,流量起飞
  • OpenAI最强ChatGPT智能体发布:技术突破与应用前景分析
  • 前端项目利用Gitlab CI/CD流水线自动化打包、部署云服务
  • 乙烯丙烯酸酯橡胶市场报告:性能优势、行业现状与发展前景​
  • 【现有资料整理】灵枢 - 用于医学领域的 SOTA 多模态大语言模型
  • Java Set 集合详解:从基础语法到实战应用,彻底掌握去重与唯一性集合
  • Pythonday17
  • 群晖中相册管理 immich大模型的使用
  • C++ :vector的介绍和使用
  • MyBatis:配置文件完成增删改查_添加
  • 【RAG实战】用户反馈如何关联算法优化
  • Redisson 分布式锁
  • 构建智能客服Agent:从需求分析到生产部署
  • 使用 jar -xvf 解压JAR文件无反应怎么办?
  • 打车代驾 app 订单管理系统模块搭建
  • IDEA高效开发:Database Navigator插件安装与核心使用指南
  • Android studio和gradle升级后的一些错误
  • 进阶向:智能图像增强系统
  • 零售快销行业中线下巡店AI是如何颠覆传统计算机视觉识别的详细解决方案
  • Python爬虫入门到实战(3)-对网页进行操作
  • Linux 定时任务全解析:atd 与 crond 的区别及实战案例(含日志备份 + 时间写入)
  • 黑马Node.js全套入门教程,nodejs新教程含es6模块化+npm+express+webpack+promise等_ts对象笔记
  • 【问题解决】npm包下载速度慢
  • AI与BI的融合挑战:Strategy平台的差异化优势
  • 小白学Python,网络爬虫篇(2)——selenium库
  • (5)颜色的灰度,亮度,对比度,透明度,都啥意思
  • 零基础入门:用按键精灵实现视频自动操作(附完整脚本)
  • Instagram千号矩阵:亚矩阵云手机破解设备指纹检测的终极方案