我很好奇 C# 在将值/引用类型传递给方法时的行为方式。我想将一个装箱值类型传递给方法“AddThree”。这个想法是在调用函数 (Main) 中获取在“AddThree”中执行的操作的结果。
static void Main(string[] args)
{
int age = 3;
object myBox = age;
AddThree(myBox);
// here myBox = 3 but I was expecting to be = 6
}
private static void AddThree(object age2)
{
age2 = (int)age2 + 3;
}
我已经用像 string 这样的纯引用类型试过了,我得到了相同的结果。如果我在一个类中“包装”我的 int 并在此示例中使用“包装”类,它会按预期工作,即,我得到 myBox = 6。如果我修改“AddThree”方法签名通过 ref 传递参数,这也返回 6。但是,我不想修改签名或创建包装类,我只想装箱值。
最佳答案
I don't want to modify the signature or create a wrapper class, I want to just box the value.
那就麻烦了。你的方法传递一个装箱的 int
,然后将它拆箱并将 3 添加到本地 age2
,这会导致另一个装箱操作,然后丢弃该值。事实上,您正在将 age2
分配给堆上的两个不同对象,它们不指向同一个对象。
如果不修改方法签名,这是不可能的。
如果您查看为 AddThree
生成的 IL,您会清楚地看到:
AddThree:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: unbox.any System.Int32 // unbox age2
IL_0007: ldc.i4.3 // load 3
IL_0008: add // add the two together
IL_0009: box System.Int32 // box the result
IL_000E: starg.s 00
IL_0010: ret
您取消装箱该值,添加 3,然后再次装箱该值,但您永远不会返回它。
为了进一步形象化这种情况,尝试从方法中返回新装箱的值(只是为了测试),并使用 object.ReferenceEquals
比较它们:
static void Main(string[] args)
{
int age = 3;
object myBox = age;
var otherBox = AddThree(myBox);
Console.WriteLine(object.ReferenceEquals(otherBox, myBox)); // False
}
private static object AddThree(object age2)
{
age2 = (int)age2 + 3;
return age2;
}
关于c# - 装箱值类型以将其发送到方法并获取结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33844438/