在.net中,一个对象会发生什么变化
本文关键字:什么 变化 一个对象 net | 更新日期: 2023-09-27 17:58:42
我想知道在进行强制转换时对象会发生什么。对象的布局是否被重新构造,方法表是否发生了更改,或者只是为了确保我的赋值在运行时不会中断?
诚实的答案是这取决于。有些转换类型只涉及装箱和取消装箱,这只会改变代码在运行时的解释方式。底层对象实际上并没有改变。例如,这种类型的强制转换涉及从string
到object
之间的强制转换(因为string
是object
,C#中的所有内容也是如此)。
http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx
或者,如果涉及自定义/用户定义的强制转换运算符,那么任何事情都可能发生。强制转换可以创建一个全新的对象,该对象表示已强制转换的原始对象。这种类型的强制转换的一个示例是int
到string
。
http://msdn.microsoft.com/en-us/library/09479473.aspx
正如所有其他人所指出的,强制转换本身不会改变被强制转换的对象。
也就是说,关于重载显式转换行为的能力有一点值得注意,显式转换乍一看是强制转换。如果一个类型重载了显式转换运算符,那么它可以(尽管它真的不应该)更改要转换的对象。
public class EvilClass
{
public int SomeProperty { get; set; }
public static explicit operator SomeOtherType(B bObj)
{
obj.SomeProperty = -1;
return SomeOtherType.CreateFromEvilClass(bObj);
}
}
然后,对用户来说,这看起来像一个演员阵容:
EvilClass evilClass = new EvilClass();
evilClass.SomeProperty = 42;
SomeOtherType sot = (SomeOtherType)evilClass; // looks like cast..
Console.WriteLine(evilClass.SomeProperty); // Will print -1, not 42
什么都没有。强制转换改变了指针指向的逻辑假设。
对象中的任何内容都不会改变——所发生的只是检查对象是否为假定类型。
如果你有A和B:A,并且A=新的A()
然后基本上
var B=(B)
要求编译器检查A是否真的是B.
现在,如果一个被创建为C(C:a)的实例,那么-这可以并且将在这一点上爆炸。
如果强制转换引用类型,则不会发生任何事情。这只是一个运行时检查,以确定对象实际上是指定类型的。在某些情况下(如Byte
到Double
),该值将更改以匹配新的数据类型。实际上,它不会改变,但您将获得代表相同值的新数据类型的新值。如果涉及到用户定义的转换,则取决于实现会发生什么。
通常底层数据不会发生任何变化——它只是决定代码如何与对象交互。
然而,一些"强制转换"实际上会进行转换,这意味着它们会更改对象的底层数据。
例如:
(double)(int)1.1;
将1.1转换为整数(截断为1),然后将转换回为double
,在本例中返回1.0。
您还可以定义引用类型的显式转换:
public static explicit operator Celsius(Fahrenheit fahr)
{
return new Celsius((5.0f / 9.0f) * (fahr.degrees - 32));
}
Fahrenheit fahr = new Fahrenheit(100.0f);
Console.Write("{0} Fahrenheit", fahr.Degrees);
Celsius c = (Celsius)fahr;
请注意,技术上原始数据在这两种情况下都没有改变-强制转换返回一个带有新数据的新对象。
无!
你所做的只是"假装"它是另一种类型。当然,如果它不是从该类型继承的(或者在下转换时实际上是该类型的实例),则转换失败,并且在使用"as"运算符进行转换时一无所获(null),显式(C样式)转换将抛出。
除非,也就是说,您正在处理值类型(尤其是数字类型)。如果您执行以下操作:
double myDouble = 1.5f;
int myInt = (int)myDouble;
double myOtherDouble = (double)myInt;
myInt和myOtherDouble将得到1,因为在执行转换时会截断该数字。大多数其他值类型甚至不支持这种类型的强制转换,因为转换没有定义。