C# 铸造和转化之间有什么区别?

C# 铸造和转化之间有什么区别?,c#,type-conversion,casting,C#,Type Conversion,Casting,埃里克·利珀特的评论让我彻底困惑。C#中的铸造和转换有什么区别?就我的理解,可能太简单了: 在强制转换时,基本数据保持不变(相同的内部表示)-“我知道这是一个字典,但您可以将其用作ICollection” 转换时,您正在将内部表示形式更改为其他形式-“我希望此int为字符串”。强制转换是一种告诉编译器“对象X实际上是Y类型,请继续并将其视为Y类型”的方式 转换是说“我知道对象X不是类型Y,但是有一种方法可以从类型Y的X创建一个新对象,继续做吧。”我相信Eric想说的是: Casting是一个描述

埃里克·利珀特的评论让我彻底困惑。C#中的铸造和转换有什么区别?

就我的理解,可能太简单了:

在强制转换时,基本数据保持不变(相同的内部表示)-“我知道这是一个字典,但您可以将其用作ICollection”


转换时,您正在将内部表示形式更改为其他形式-“我希望此int为字符串”。

强制转换是一种告诉编译器“对象X实际上是Y类型,请继续并将其视为Y类型”的方式


转换是说“我知道对象X不是类型Y,但是有一种方法可以从类型Y的X创建一个新对象,继续做吧。”

我相信Eric想说的是:


Casting是一个描述语法的术语(因此是语法意义)

转换是一个术语,描述在幕后实际采取的行动(以及语义)

强制转换表达式用于转换 显式地将表达式指定给给定的 类型

(T)E形式的演员表, 其中T为a型,E为a型 一元表达式,执行显式 E值的换算(§13.2) 输入T


似乎通过说语法中的cast操作符执行显式转换来支持这一点。

在本文中,cast意味着您要将给定类型的对象作为其他类型公开以进行操作,转换意味着您实际上正在将一个给定类型的对象更改为另一个类型的对象。

的MSDN C#文档表明转换是特定的转换实例:“显式转换”。也就是说,形式
x=(int)y
的转换是转换


自动数据类型更改(例如
myLong=myInt
)是更通用的“转换”。

阅读Eric的评论后,尝试用简单的英语:

铸造意味着这两种类型在某种程度上实际上是相同的。它们可以实现相同的接口或从相同的基类继承,或者目标可以“足够相同”(超集?),以便转换工作,例如从Int16转换到Int32

转换类型意味着这两个对象可能非常相似,可以进行转换。以数字的字符串表示为例。它是一个字符串,不能简单地转换为一个数字,需要对它进行解析并从一个转换为另一个,并且,该过程可能会失败。铸造也可能失败,但我认为这是一个成本低得多的失败

这就是我认为这两个概念之间的关键区别。转换将需要某种解析,或者对源数据进行更深入的分析和转换。强制转换不解析。它只是尝试在某个多态级别进行匹配。

来自C#Spec 14.6.6:

强制转换表达式用于转换 显式地将表达式指定给给定的 类型。

(T)E形式的演员表, 其中T为a型,E为a型 一元表达式,执行显式 E值的换算(§13.2) 输入T

因此,casting是一种语法构造,用于指示编译器调用显式转换

根据C#Spec§13:

转换可启用以下表达式: 将一种类型视为另一种类型 类型。转换可以是隐式的,也可以是 显式,这决定了 需要显式强制转换。 [示例:例如,转换 从int类型到long类型是 隐式,因此int类型的表达式 可以隐式地视为类型 长。相反的转换,从 类型long到类型int,是显式的,所以 需要显式强制转换


因此,转换是实际工作完成的地方。您会注意到,cast表达式引号表示它执行显式转换,但显式转换是隐式转换的超集,因此您也可以调用隐式转换(即使您不需要)通过强制转换表达式。

强制转换是从另一种类型的值创建一种类型的值。转换是一种强制转换类型,其中值的内部表示形式也必须更改(而不仅仅是其解释)

在C#中,强制转换和转换都是通过强制转换表达式完成的:

(类型)一元表达式

这一区别很重要(注释中指出了这一点),因为转换运算符声明符只能创建转换。因此,代码中只能创建(隐式或显式)转换


非转换隐式转换始终可用于子类型到超类型转换,非转换显式转换始终可用于超类型到子类型转换。不允许其他非转换转换转换。

转换是类/结构上的运算符。转换是一个或另一个受影响类/结构上的方法/进程,或者可能位于完全不同的类/结构中(即
Converter.ToInt32()

Cast操作符有两种类型:隐式和显式

隐式转换运算符表示一种类型(例如Int32)的数据始终可以表示为另一种类型(decimal),而不会丢失数据/精度

显式强制转换运算符表示一种类型(十进制)的数据始终可以忠实地表示为另一种类型(int),但可能会丢失数据/精度。因此,编译器要求您显式声明您知道这一点,并且无论如何都要使用显式强制转换语法:

decimal d = 25.0001;
int i = (int)d;
转换采用两种不一定以任何方式相关的类型,并尝试通过某些过程(如解析)将一种转换为另一种。如果所有已知的转换算法都失败,则该过程可能引发异常或返回默认值:

string s = "200";
int i = Converter.ToInt32(s); // set i to 200 by parsing s

string s = "two hundred";
int i = Converter.ToInt32(s); // sets i to 0 because the parse fails
埃里克的
string s = "200";
int i = Converter.ToInt32(s); // set i to 200 by parsing s

string s = "two hundred";
int i = Converter.ToInt32(s); // sets i to 0 because the parse fails
Object o = float.NaN;
String s = (String) o;
int x = 1;
int y = (int)x;
Giraffe g = new Giraffe();
Animal a = (Animal)g;
// (None : Option[Int]) casts None to Option[Int]
println(Some(7) <*> ((None : Option[Int]) <*> (Some(9) > add)))