gpt4 book ai didi

c# - 装箱在 C# 和 VB 中的行为不同

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

我正在尝试将结构传递给 sub/void 以用数据填充它。在 C# 中,这可以正常工作

[TestFixture]
public class Boxing
{
[Test]
public void BoxingValue()
{
var res = (object)new Test();
SomeVoid(res);
Assert.AreEqual(2, ((Test)res).Id);
}

public static void SomeVoid(object b)
{
var f = b.GetType().GetField("Id");
f.SetValue(b, 2);
}

public struct Test
{
public int Id;
}
}

此代码在 vb 中通过了 C# 测试

<Test> Public Sub StructTest()
Dim s As Object
s = CObj(New Test)
A(s)
Assert.AreEqual(2, CType(s, Test).Id)
End Sub

Public Sub A(val As Object)
Dim f = val.GetType().GetField("Id")
f.SetValue(val, 2)
End Sub

Public Structure Test
Public Id As Integer
End Structure

有没有人对此有解释......

奇怪?

最佳答案

我相信这是在传递结构时在 VB 中使用 SetValue 的已知限制(即使变量本身被声明为 Object)。如果您在调用 SetValue 之前和之后查看 Aval 的内容,您会发现它并没有改变结构的值。我看到的解释是,VB 在内部将基础值再次(通过调用 GetObjectValue)装箱,创建一个副本,然后更改副本的值(value)。

我见过的一种解决方法是将值转换为 ValueType 并对其调用 SetValue(您还需要将参数显式更改为 ByRef:

Public Sub A(ByRef val As Object)
Dim f = val.GetType().GetField("Id")
If val.GetType.IsValueType Then
Dim vt As ValueType = val
f.SetValue(vt, 2)
val = vt
Else
f.SetValue(val, 2)
End If
End Sub

当然,这种复杂性只是强化了应不惜一切代价避免可变结构的原则。

关于c# - 装箱在 C# 和 VB 中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26612912/

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