详解c# 强制转换和类型转换

由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或无法分配另一种类型的值,除非该类型可以隐式转换为变量的类型。 例如,string 无法隐式转换为 int。 因此,在将 i 声明为 int 后,无法将字符串“Hello”分配给它,如以下代码所示:

int i;

// error CS0029: Cannot implicitly convert type 'string' to 'int'
i = "Hello";

但有时可能需要将值复制到其他类型的变量或方法参数中。 例如,可能需要将一个整数变量传递给参数类型化为 double 的方法。 或者可能需要将类变量分配给接口类型的变量。 这些类型的操作称为类型转换。 在 C# 中,可以执行以下几种类型的转换:

  • 隐式转换:由于这种转换始终会成功且不会导致数据丢失,因此无需使用任何特殊语法。 示例包括从较小整数类型到较大整数类型的转换以及从派生类到基类的转换。
  • 显式转换(强制转换) :必须使用强制转换表达式,才能执行显式转换。 在转换中可能丢失信息时或在出于其他原因转换可能不成功时,必须进行强制转换。 典型的示例包括从数值到精度较低或范围较小的类型的转换和从基类实例到派生类的转换。
  • 用户定义的转换:用户定义的转换是使用特殊方法执行,这些方法可定义为在没有基类和派生类关系的自定义类型之间启用显式转换和隐式转换。
  • 使用帮助程序类进行转换:若要在非兼容类型(如整数和 System.DateTime 对象,或十六进制字符串和字节数组)之间转换,可使用 System.BitConverter 类、System.Convert 类和内置数值类型的 Parse 方法(如 Int32.Parse)。

隐式转换

对于内置数值类型,如果要存储的值无需截断或四舍五入即可适应变量,则可以进行隐式转换。 对于整型类型,这意味着源类型的范围是目标类型范围的正确子集。 例如,long 类型的变量(64 位整数)能够存储 int(32 位整数)可存储的任何值。 在下面的示例中,编译器先将右侧的 num 值隐式转换为 long 类型,再将它赋给 bigNum。

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;

有关所有隐式数值转换的完整列表,请参阅内置数值转换一文的隐式数值转换表部分。
对于引用类型,隐式转换始终存在于从一个类转换为该类的任何一个直接或间接的基类或接口的情况。 由于派生类始终包含基类的所有成员,因此不必使用任何特殊语法。

Derived d = new Derived();

// Always OK.
Base b = d;

显式转换

但是,如果进行转换可能会导致信息丢失,则编译器会要求执行显式转换,显式转换也称为强制转换。 强制转换是显式告知编译器以下信息的一种方式:你打算进行转换且你知道可能会发生数据丢失,或者你知道强制转换有可能在运行时失败。 若要执行强制转换,请在要转换的值或变量前面的括号中指定要强制转换到的类型。 下面的程序将 double 强制转换为 int。如不强制转换则该程序不会进行编译。

class Test
{
 static void Main()
 {
 double x = 1234.7;
 int a;
 // Cast double to int.
 a = (int)x;
 System.Console.WriteLine(a);
 }
}
// Output: 1234

有关支持的显式数值转换的完整列表,请参阅内置数值转换一文的显式数值转换部分。
对于引用类型,如果需要从基类型转换为派生类型,则必须进行显式强制转换:

// Create a new derived type.
Giraffe g = new Giraffe();

// Implicit conversion to base type is safe.
Animal a = g;

// Explicit conversion is required to cast back
// to derived type. Note: This will compile but will
// throw an exception at run time if the right-side
// object is not in fact a Giraffe.
Giraffe g2 = (Giraffe)a;

引用类型之间的强制转换操作不会更改基础对象的运行时类型;它只更改用作对该对象引用的值的类型。 有关详细信息,请参阅多态性。

运行时的类型转换异常

在某些引用类型转换中,编译器无法确定强制转换是否会有效。 正确进行编译的强制转换操作有可能在运行时失败。 如下面的示例所示,类型转换在运行时失败将导致引发 InvalidCastException。

class Animal
{
 public void Eat() => System.Console.WriteLine("Eating.");

 public override string ToString() => "I am an animal.";
}

class Reptile : Animal { }
class Mammal : Animal { }

class UnSafeCast
{
 static void Main()
 {
 Test(new Mammal());

 // Keep the console window open in debug mode.
 System.Console.WriteLine("Press any key to exit.");
 System.Console.ReadKey();
 }

 static void Test(Animal a)
 {
 // System.InvalidCastException at run time
 // Unable to cast object of type 'Mammal' to type 'Reptile'
 Reptile r = (Reptile)a;
 }
}

Test 方法有一个 Animal 形式参数,因此,将实际参数 a 显式强制转换为 Reptile 会造成危险的假设。 更安全的做法是不要做出假设,而是检查类型。 C# 提供 is 运算符,使你可以在实际执行强制转换之前测试兼容性。 有关详细信息,请参阅如何使用模式匹配以及 as 和 is 运算符安全地进行强制转换。

以上就是详解c# 强制转换和类型转换的详细内容,更多关于c# 强制转换和类型转换的资料请关注我们其它相关文章!

(0)

相关推荐

  • c# 使用模式匹配以及 is 和 as 运算符安全地进行强制转换

    由于是多态对象,基类类型的变量可以保存派生类型. 要访问派生类型的实例成员,必须将值强制转换回派生类型. 但是,强制转换会引发 InvalidCastException 风险. C# 提供模式匹配语句,该语句只有在成功时才会有条件地执行强制转换. C# 还提供 is 和 as 运算符来测试值是否属于特定类型. 下面的示例演示如何使用模式匹配 is 语句: class Animal { public void Eat() { Console.WriteLine("Eating."); }

  • C#中is与As运算符号的使用详解

    如下所示: 复制代码 代码如下: using System;using System.Collections.Generic;using System.Text;namespace ConsoleApplication1{    class IsOrAsClass    {        class Animal        {            public void Eat()            {                Console.WriteLine("Eating.

  • C#8 的模式匹配实现

    C# 7 里面的Pattern Mathing 更多内容请查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8#more-patterns-in-more-places?WT.mc_id=DT-MVP-5003302 is 模式 switch 和 when C# 8 里面的Pattern Matching 使用Deconstructor 和 位置匹配模式 下面两个类Teacher和Student都由构造函

  • C#日期格式强制转换方法(推荐)

    C#编写winform程序时,用到的,格式强转,存储到数据库,数据库连接那块就不写了 希望对大家有帮助,欢迎评论互相分享技术! //日期格式强制转化 string str1 = deStartDate.EditValue.ToString(); DateTime date; DateTime.TryParse(str1, out date); str1 = date.ToString("yyyy/MM/dd"); string str2 = deDueDate.EditValue.To

  • C#自定义类型强制转换实例分析

    本文实例讲述了C#自定义类型强制转换的用法.分享给大家供大家参考.具体分析如下: 先来举一个小例子 类定义: public class MyCurrency { public uint Dollars; public ushort Cents; public MyCurrency(uint dollars, ushort cents) { this.Dollars = dollars; this.Cents = cents; } public override string ToString()

  • C#强制转换和尝试转换的方法

    本文实例为大家分享了C#强制转换和尝试转换的方法,供大家参考,具体内容如下 将String[]类型的Object类型,转换为String[]类型: public string ObjectToString(object ob) { string str = string.Empty; if (ob is string[]) { string[] strList = (string[])ob; } return str; } 使用 is 进行判断 ob 是否为 string[] 类型. 将 str

  • C# 9.0 新特性之模式匹配简化的实现

    记得在 MS Build 2020 大会上,C# 语言开发项目经理 Mads Torgersen 宣称 C# 9.0 将会随着 .NET 5 在今年 11 月份正式发布.目前 .NET 5 已经到了 Preview 5 阶段了,C# 9.0 也已经初具规模.忍不住激动的心情,暂停更新<C#.NET 拾遗补漏>系列几天,先要和大家分享一下我了解到的 C# 9.0 的新特性.由于新特性比较多,所以会分成几篇来讲.这是第一篇,专讲模式匹配这个特性的简化. 模式匹配(Pattern Matching)

  • 详解c# 强制转换和类型转换

    由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或无法分配另一种类型的值,除非该类型可以隐式转换为变量的类型. 例如,string 无法隐式转换为 int. 因此,在将 i 声明为 int 后,无法将字符串"Hello"分配给它,如以下代码所示: int i; // error CS0029: Cannot implicitly convert type 'string' to 'int' i = "Hello"; 但有时可能需要将值复制到其他类

  • 详解Java对象转换神器MapStruct库的使用

    目录 前言 MapStruct简介 MapStruct入门 1. 引入依赖 2. 需要转换的对象 3. 创建转换器 4. 验证 5. 自动生成的实现类 MapStruct进阶 场景1:属性名称不同.(基本)类型不同 场景2:统一映射不同类型 场景3:固定值.忽略某个属性.时间转字符串格式 场景4:为某个属性指定转换方法 场景5:多个参数合并为一个对象 场景6:已有目标对象,将源对象属性覆盖到目标对象 场景7:源对象两个属性合并为一个属性 小结 前言 在我们日常开发的程序中,为了各层之间解耦,一般

  • 详解解密Java中的类型转换问题

    众所周知Java中的数据类型是强数据类型,基本数据类型之间的转换尤其固定的规则,当数据宽度比较窄的数据类型(如int)转换成数据类型比较宽的数据类型时(如double),则窄的数据类型会加宽,可以完成自动类型转换,这称为隐式转换. 如:以下代码没有任何问题,结果也是正确的,成绩不会发生变化,所不同的是成绩的精度提高了. intintScore = 96; doubledoubleScore = intScore; 那么如果试图把宽的数据类型(如double)转换成窄的数据类型(如float)时,

  • 详解Swift中的数据类型类型转换

    一.类型检查与转换 在Objective-C和Java中,任何类型实例都可以通过强转使编译器认为它是另一种类型的实例,这么做其实是将所有的安全检查工作都交给了开发者自己来做.先比之下,Swift中的Optional类型转换就会比较安全与可靠. Swift中使用is关键字来进行类型的检查,其会返回一个布尔值true或者false来表明检查是否成立,示例如下: var str = "HS" if str is String { print(str) } Swift中有向上兼容与向下转换的特

  • 详解Java多态对象的类型转换与动态绑定

    Java多态对象的类型转换 这里所说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象.当对不存在继承关系的对象进行强制类型转换时,java 运行时将抛出 java.lang.ClassCastException 异常. 在继承链中,我们将子类向父类转换称为"向上转型",将父类向子类转换称为"向下转型". 很多时候,我们会将变量定义为父类的类型,却引用子类的对象,这个过程就是向上转型.程序运行时通过动态绑定来实现对子类方法的调用,也就是多态性. 然而有些时候

  • 详解C语言基础的类型转换

    目录 类型转换 隐式类型转换 强制类型转换 总结 类型转换 数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题.转换包括隐式类型转换和强制类型转换. 类型转换的原则:占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低. 隐式类型转换 隐式转换也称为自动转换,遵循一定的规则,由编译器自动完成. C的整型算数运算总是至少以缺省整型类型的精度来进行,为了获得这个精度,表达式中的字符和短整形操作数在使用之前都被转换成普通整型,这种转换为整型提

  • 详解PHP编码转换函数应用技巧

    在PHP中有数量庞大的函数来支持我们的需求应用.下面介绍的这个函数就是有关PHP编码转换函数.希望对大家有所帮助.mb_convert_encoding 函数为PHP内部多字节字符串编码转换函数. 可以在有需要的使用场合(如:解决在GB2312编码环境下使用Ajax产生的中文字乱码的问题)方便进行编码转换,以解决网页乱码的问题,使用非常方便,效率非常高,几乎支持所有编码.PHP 4 >= 4.0.6.PHP 5 版本支持. PHP编码转换函数原型: /**  * 多字节字符串编码转换函数  * 

  • 详解SpringMVC注解@initbinder解决类型转换问题

    在使用SpringMVC的时候,经常会遇到表单中的日期字符串和JavaBean的Date类型的转换,而SpringMVC默认不支持这个格式的转换,所以需要手动配置,自定义数据的绑定才能解决这个问题. 在需要日期转换的Controller中使用SpringMVC的注解@initbinder和Spring自带的WebDateBinder类来操作. WebDataBinder是用来绑定请求参数到指定的属性编辑器.由于前台传到controller里的值是String类型的,当往Model里Set这个值的

  • 详解docker强制批量删除none的image镜像

    说正题,今天遇到的问题是自己在开发机做坏了几个image镜像,删不了   我想大家也遇到过这样类似的问题  -. 他的名字和tag都是为none,空- 以前看过一个帖子说,给他标记一个tag,就可以干掉,瞎扯- [ruifengyun@bj-buzz-dev01 extractor_docker]$ [ruifengyun@bj-buzz-dev01 extractor_docker]$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL

  • C++类型转换运算符的实例详解

    C++类型转换运算符的实例详解 C++中有4个类型转换运算符,使装换过程更规范 dynamic_cast; const_cast; static_cast; reinterpret_cast; 一.dynamic_cast 该运算符我在之前的文章中已经介绍过了 http://www.jb51.net/article/123252.htm 总之,该运算符的语法如下: dynamic_cast < type-name> (expression) 如果转型失败则返回0,即空指针. 该运算符的用途是,

随机推荐