3

最近我在学习值类型,我有点困惑。此外,铸造和拆箱都使用相同的语法 - (预期类型)(对象),对吗?那么类型之间的简单转换呢,即转换还​​是转换?

int x = (int)2.5; //casting?

object a=x;
int Y=(int)a;  //unboxing I think

Random r=new Random();
object X=r;
Random R=(Random)X;  // casting
4

5 回答 5

9

这里有很多事情要考虑,但让我们先解决最简单的问题:

语法是什么(type)expression

好吧,在其基本形式中,它被认为是铸造。您将表达式从一种类型转换为另一种类型。就是这样。

但是,究竟会发生什么,这取决于类型和许多其他事情。

如果将值类型转换为其他类型,则依赖于所涉及的两种类型之一来声明处理此问题的转换运算符。换句话说,值类型需要定义一个可以转换为该其他类型的转换运算符,或者该其他类型需要定义一个可以从原始类型转换的转换运算符。

该运算符的作用取决于该运算符的作者。这是一种方法,所以它可以做任何事情。

将值类型转换为其他类型会为您提供不同的值、单独的值类型或新的引用类型,其中包含转换后的新数据。

例子:

int a = (int)byteValue;

当您将值类型转换为引用类型(通常是object)或值类型实现的接口之一时,装箱和拆箱就会发挥作用。

例子:

object o = intValue; // boxing
int i = (int)o;      // unboxing

投射到界面时,拳击也会发挥作用。假设“someValueType”是一个结构,它也实现了 IDisposable:

IDisposable disp = (IDisposable)someValueType; // boxed

转换引用类型,也可以做其他事情。

首先,您可以定义与值类型相同的转换运算符,这意味着将一种引用类型转换为另一种引用类型可以返回一个全新的对象,其中包含完全不同类型的信息。

转换引用类型时,装箱不会起作用,除非您将引用类型转换回值类型(见上文。)

例子:

string s = (string)myObjectThatCanBeConvertedToAString;

或者,您可以重新解释引用,以便您仍然引用有问题的同一对象,但您正在通过一副不同类型的眼镜来查看它。

例子:

IDisposable disp = (IDisposable)someDisposableObject;
于 2011-01-19T11:53:41.223 回答
3

拆箱的一个重要限制是您只能拆箱为确切的值类型(或其可为空的等效项),而不能拆箱为原始值类型可转换为的另一种值类型。

int myInt = 1;
object x = myInt; // box
int  unbox1 = (int)x;  // successful unbox
int? unbox2 = (int?)x; // successful unbox
long unbox3 = (long)x; // error. Can't unbox int to long
long unbox4 = (long)(int)x; // works. First it unboxes to int, and then converts to long

另一个有趣的地方是,一个可以为空的值类型被装箱为它的不可为空的类型,并且可以被拆箱为可以为空的和不可为空的类型。由于具有值的可空对象null框到引用null,因此有关其类型的信息在装箱期间丢失。

于 2011-01-19T12:02:29.733 回答
1

演员表基本上是一种转换形式。

您代码中的所有注释都是正确的。

然而,重要的是要注意参考转换和其他转换之间的区别。您显示的最终转换是引用转换 - 它维护表示身份,因此 和 的值X都是R对同一对象的引用。

将此与double转换int(显着更改形式)和拆箱(将值从框内复制到变量)进行比较。

这种差异对于某些主题很重要,例如泛型方差- 由于引用转换可用,它仅适用于引用类型。基本上,CLR 检查所有类型是否适当,然后运行适当的代码,而无需对引用本身执行任何实际转换。

于 2011-01-19T11:48:11.537 回答
1

装箱和拆箱专门指将值类型转换为引用类型并再次转换回来。查看此链接以获取更多装箱和拆箱(C# 编程指南)

于 2011-01-19T11:48:18.397 回答
0

装箱和拆箱由编译器在幕后完成。所以正确的评论是

int x = (int)2.5; //casting with conversion

object a=x; //casting with boxing
int Y=(int)a;  //casting with unboxing

Random r=new Random();
object X=r;
Random R=(Random)X;  //casting without unboxing

关于铸造与转换检查这个问题:铸造和转换之间有什么区别?

于 2011-01-19T11:47:59.173 回答