我正在尝试将结构传递给子/ 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;
}
}
Run Code Online (Sandbox Code Playgroud)
此代码在vb thoug中通过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
Run Code Online (Sandbox Code Playgroud)
有没有人对此有解释..
奇怪?
我相信这是一个已知的限制,SetValue在传递结构时使用VB(即使变量本身被声明为Object).如果你看的内容val中A前和呼叫后SetValue,你会看到,它不改变结构的价值.我看到的解释是VB在内部再次封装基础值(通过调用GetObjectValue),创建副本,并更改副本的值.
我看到的一个解决方法是将值转换为a 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
Run Code Online (Sandbox Code Playgroud)
当然,这种复杂性只是强调了应该不惜一切代价避免可变结构的原则.