一,在程序中我们经常会遇到:无法将类型“XXX”隐式装换为“XXX”,如下例子:

  1.     static void Main(string[] args)
  2. {
  3. int i;
  4. i = "Hello World";
  5. }

那这是什么原因呢?

由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或者无法用于存储其他类型的值,除非该类型可以转换为变量的类型。 例如,不存在从整数到任意字符串的转换。 因此,在将 i 声明为整数后,无法将字符串“Hello World”赋予它.

二, 在 C# 中,常见的两种类型的转换:

1》隐式转换:

1,系统默认的、不需要加以声明就可以进行的转换,在隐式转换过程中,编译器无需对转换进行详细检查就能够安全地执行转换。

2,该转换是一种类型安全的转换,不会导致数据丢失,因此不需要任何特殊的语法。

PS:示例包括从较小整数类型到较大整数类型的转换(从int到float的转换)以及从派生类到基类的转换(子类到父类)。

2》显式转换(强制转换):

1,显式转换需要用户明确地指定转换的类型

2,显式转换需要强制转换运算符。 在转换中可能丢失信息时或在出于其他原因转换可能不成功时,必须进行强制转换。

PS:典型的示例包括从数值到精度较低或范围较小的类型的转换(float到int的转换)和从基类实例到派生类的转换(父类到子类)。

三,那为什么隐式转换不会导致数据丢失,而显示转换会?

1》隐式转换不会丢失原因:对于内置数值类型,如果要存储的值无需截断或四舍五入即可适应变量,则可以进行隐式转换。

例如,long 类型的变量(8 字节整数)能够存储 int(在 32 位计算机上为 4 字节)可存储的任何值。 在下面的示例中,编译器先将右侧的值隐式转换为 long 类型,再将它赋给 longNum

  1.        int intnum = ;
  2. long longNum = intnum;
  3. Console.WriteLine(longNum);

2》显示转换如下:

  1.       //错误:无法将类型“double”隐式转换为“int”。存在一个显式转换(是否缺少强制转换?)
  2. double x = 1234.4567;
  3. int a;
  4. a = x;
  5. Console.WriteLine(a);

下面的程序将 double 强制转换为 int。 如不强制转换则该程序不会进行编译,并有无法将类型“double”隐式转换为“int”。存在一个显式转换(是否缺少强制转换?)

这样的意思是:当我们在将精度大的转换为精度小的(或者父类转换为子类时),这时就是显示转换,但是当我们存在显示转换而没有强制转换的时候编辑就会报错,如下解决:

  1. double x = 1234.4567;
  2. int a;
  3. a = (int)x;
  4. Console.WriteLine(a);

但是这个时候,我们输出的值就是int的精度的值,就是1234

三,那引用类型的隐式和显示转换又是怎样的呢?如下例子:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace TypeDemo2
  7. {
  8. class Program
  9. {
  10. static void Main()
  11. {
  12. //派生类是继承基类过来的,所有基类有的定义它都会有,所以这样的隐式转换是被认为合法的
  13. Animal a = new Dog();
  14. a.Eat();
  15. //然而基类类型不能隐式转换为派生类,因为派生类中的成员定义在基类中是不一定存在的
  16. //Dog d = new Animal();
  17.  
  18. //同时基类类型不能显示转换为派生类,强转也是报错的
  19. //Animal aa = new Animal();
  20. //Dog d = (Dog)aa;
  21. //d.Eat();
  22.  
  23. //在理解隐式和显式的时候还有一个误区,如下,神奇的事发生了,不是基类不能隐式转换为派生类么?
  24. //以下代码的理解是:虽然类型是Animal,但是他的实际的值还是指向余内存的Dog这块空间,所以当你使用AS dog时候不会报错
  25. Animal a1 = new Dog();
  26. Dog d = a1 as Dog;
  27. //a1.Say(); //这样写报错
  28. d.Eat();
  29. d.Say();
  30. }
  31. }
  32. class Animal
  33. {
  34. public void Eat()
  35. {
  36. Console.WriteLine("吃!!!");
  37. }
  38. }
  39. class Dog : Animal
  40. {
  41.  
  42. public void Say()
  43. {
  44. Console.WriteLine("汪汪");
  45. }
  46. }
  47.  
  48. }

综上:引用类型的隐式转换是合法的(派生类转换成基类,子类转换成父类),而反之报错,因为派生类成员定义不一定子在基类中存在

C#隐式类型和显示类型的更多相关文章

  1. 【C++自我精讲】基础系列五 隐式转换和显示转换

    [C++自我精讲]基础系列五 隐式转换和显示转换 0 前言 1)C++的类型转换分为两种,一种为隐式转换,另一种为显式转换. 2)C++中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换. 1 隐 ...

  2. C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解

    模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始 ...

  3. C# 3.0 / C# 3.5 隐式(推断)类型 var

    概述 你可能对隐式类型(或隐式推断类型)这个名称比较陌生,但是 var 这个关键字应该很熟悉. 在 C# 中使用 var 声明一个对象时编译器会自动根据赋值语句推断这个局部变量的类型. 赋值以后,这个 ...

  4. ahjesus自定义隐式转换和显示转换

    implicit    关键字用于声明隐式的用户定义类型转换运算符. 如果可以确保转换过程不会造成数据丢失,则可使用该关键字在用户定义类型和其他类型之间进行隐式转换. 参考戳此 explicit    ...

  5. android intent 隐式意图和显示意图(activity跳转)

    android中的意图有显示意图和隐式意图两种, 显示意图要求必须知道被激活组件的包和class 隐式意图只需要知道跳转activity的动作和数据,就可以激活对应的组件 A 主activity  B ...

  6. C#隐式转换和显示转换举例--C#基础

    高精度的数据类型转换为低精度的数据类型是显示转换,低精度的转换为高精度的是隐式转换. 温馨提示:不能说强制类型转换是从低精度到高精度. int a=666;float b=(float)a: 由a到b ...

  7. C#隐式转换与显示转换

    System.Objec时C#中所有类型的基类,也就是万类之源. 一.值类型 值类型都继承自System.ValueType(派生自System.Objec),继承自System.ValueType的 ...

  8. C# 中的隐式类型转换(运算时的隐式转换)和显示类型转换

    区别: 隐式转换失败编译会报错. 显示转换有可能精度丢失. 根据项目的编译设置,显示转换溢出可能会报错,如果设置溢出且未使用checked检查,运行时如果发生溢出会产出未知的计算结果. 在数字运算时, ...

  9. Selenium2设置隐式等待和显示等待

    1. 设置显示等待 Java代码: public static WebElement WaitForElement(WebDriver driver, String locator) { WebEle ...

随机推荐

  1. elasticsearch 基础 —— Field Collapsing字段折叠

    允许根据字段值折叠搜索结果.通过按折叠键选择顶部排序文档来完成折叠.例如,下面的查询检索每个用户的最佳推文,并按喜欢的数量对它们进行排序. GET /twitter/_search { "q ...

  2. Spring事务中的readonly

    来源:https://www.cnblogs.com/straybirds/p/9147892.html Spring的事务经常会有这样的配置: <tx:method name="se ...

  3. shell脚本检索所有mysql数据库中没有primary key的表

    1.mkdir -p /root/scripts/ 2. cd /root/scripts/ vim query.sql,代码如下: SELECT CONCAT(t.table_schema,&quo ...

  4. 【串线篇】SQL映射文件-联合查询(完结association+cellection)

    1.级联属性的方式封装查出1-1 查钥匙的时候顺别把对应的级联的那把锁也查出来 1).两个JavaBean,Key里有对应的Lock(private Lock lock;//当前钥匙能开哪个锁:) 2 ...

  5. Java对象流与序列化学习

    对象流与序列化 对象流有两个类 ObjectOutputStream:将java对象的基本数据类型和图形写入OutputStream ObjectInputStream:对以前使用ObjectOutp ...

  6. 网络编程和并发:1.简述 OSI 七层协议

    1. 概念 Open System Interconnection : 开放互联系统 2. 图示 注:图片来源:https://www.cnblogs.com/maybe2030/p/4781555. ...

  7. mysql跟踪sql

    mysql中执行的sql跟踪比oracle简单多了,它自身有log.我们只要打开这个log记录,执行sql语句,再查看这个log就可以了.1. 首先要打开log的开关使用命令:show variabl ...

  8. JavaWeb(三):JSP

    JSP是JavaServer Page的缩写,也就是服务端网页. 一.概述 1.1 为什么使用JSP 在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变.JSP是简化Serv ...

  9. Oracle11g新建用户及用户表空间

    /* 建立数据表空间 */CREATE TABLESPACE SP_TAB DATAFILE '/u01/app/oracle/oradata/orcl/tab1_1.dbf' size 1024M ...

  10. 【优化】MySQL千万级大表优化解决方案

    问题概述 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死.严重影响业务 ...