gpt4 book ai didi

c# - 为什么在值类型上隐式调用 toString 会导致框指令

转载 作者:可可西里 更新时间:2023-11-01 08:06:51 25 4
gpt4 key购买 nike

这更像是一个“想知道为什么”而不是一个特定的问题,但请看下面的代码

        static void Main(string[] args)
{
int val = 10;

Console.WriteLine("val is {0}", val); // (1)
Console.WriteLine("val is {0}", val.ToString()); //(2)


}

情况(1)输出以下IL

IL_0000:  nop
IL_0001: ldc.i4.s 10
IL_0003: stloc.0
IL_0004: ldstr "val is {0}"
IL_0009: ldloc.0
IL_000a: box [mscorlib]System.Int32
IL_000f: call void [mscorlib]System.Console::WriteLine(string,
object)

在情况 (2) 中,我显式调用了我得到的 toString 方法

IL_0014:  nop
IL_0015: ldstr "val is {0}"
IL_001a: ldloca.s val
IL_001c: call instance string [mscorlib]System.Int32::ToString()
IL_0021: call void [mscorlib]System.Console::WriteLine(string,
object)

所以在情况 (1) 中,即使 int 重写了 toString,值类型被装箱并且调用了 toString 方法,这大概会调用 vtable 重写

所以结果是完全一样的,但是显式的 toString 避免了装箱操作

有人知道为什么吗?

=编辑=
明确一点,让我感到困惑的是,我开始假设即使 int 派生自 System.ValueType,它又派生自 System.Object,因为它包含 toString、GetHashCode 等。
因此,在我天真的观点(可能来自 C++)中,如果我覆盖派生自 System.Object 的方法,则无需强制转换为 System.Object(并因此将值类型框起来),因为存在覆盖方法并且编译器会自动引用类型的 vtable 条目。
我还假设调用 Console.WriteLine() 隐式 调用 int.toString 所以也许这就是我出错的地方。希望这是有道理的

好的 - 全部排序。谢谢大家让我直截了当。这一切都与我的错误假设有关,即 Console.WriteLine 正在执行隐式字符串转换。不要问我为什么我这么想 - 现在看来这是多么错误:)

最佳答案

您根本没有隐式调用 ToStringWriteLine 方法没有重载在格式字符串之后接收字符串,它只接收对象。

因此,您并没有隐式调用 ToString,而是隐式地将 int 转换为 object。第一种情况相当于:

Console.WriteLine("val is {0}", (object)val);

由于 int 是值类型,因此会发生装箱。

第二种情况相当于:

Console.WriteLine("val is {0}", (object)val.ToString());

由于字符串是引用类型,将其转换为对象实际上不会导致发出任何代码。它只是将类型与方法签名匹配。

关于c# - 为什么在值类型上隐式调用 toString 会导致框指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1359856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com