- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
这更像是一个“想知道为什么”而不是一个特定的问题,但请看下面的代码
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 正在执行隐式字符串转换。不要问我为什么我这么想 - 现在看来这是多么错误:)
最佳答案
您根本没有隐式调用 ToString
。 WriteLine
方法没有重载在格式字符串之后接收字符串,它只接收对象。
因此,您并没有隐式调用 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/
我是一名优秀的程序员,十分优秀!