gpt4 book ai didi

c# - 装箱值类型以将其发送到方法并获取结果

转载 作者:太空狗 更新时间:2023-10-29 18:35:08 25 4
gpt4 key购买 nike

我很好奇 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/

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