当前位置:  开发笔记 > 编程语言 > 正文

对结构的反思不同于类 - 但仅限于代码

如何解决《对结构的反思不同于类-但仅限于代码》经验,为你挑选了1个好方法。

代码段:

Dim target As Object
' target gets properly set to something of the desired type
Dim field As FieldInfo = target.GetType.GetField("fieldName", _
  BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic)
field.SetValue(target,newValue)

如果目标设置为CLASS的实例,则此代码段完美无缺.

但是,如果将target设置为STRUCTURE的实例,则代码实际上不会更改该字段的值.没有错误,但值保持不变.

而且,奇怪的是,如果我逐句通过代码,看的SetValue不能做任何事情,并立即去立即窗口,键入完全相同的setValue操作,该工程.

有关正在发生什么以及如何实际更改"代码"字段的任何建议?

编辑:

根据Jon Skeet的要求,实际代码:

Private Shared Function XmlDeserializeObject(ByVal objectType As Type, _
        ByVal deserializedID As String) As Object
    Dim result As Object
    result = CreateObject(objectType)

    mXmlR.ReadStartElement()
    Do While mXmlR.IsStartElement _
    AndAlso mXmlR.Name <> elementItem
        Dim field As FieldInfo = result.GetType.GetField(FullName, _
            BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic)
        field.SetValue(result, XmlDeserialize(field.FieldType))
    Loop

    Return result
End Function

外部变量和被调用的例程:
*mXmlR是一个XmlTextReader,并且被正确初始化和定位(否则这对类不起作用)
*CreateObject工作(同上)
*XmlDeserialize大多数工作,并且在有问题的点处理一个整数就好了.唯一已知的问题是结构.

至于我如何检查值,我主要看的是Locals窗口,但我也在立即窗口中使用了print语句,而且我正在运行一个因为这个问题而失败的NUnit测试 - 而通过类而不是结构的等效测试.

这是测试.

 Private Structure SimpleStructure
    Public MemberOne As Integer
End Structure

 Sub A016_SimpleStructure()
    Dim input As New SimpleStructure
    input.MemberOne = 3
    Dim st As String = Serialize(input)
    Debug.Print(st)
    Dim retObject As Object = Deserialize(st)
    Assert.IsNotNull(retObject)
    Assert.IsInstanceOfType(GetType(SimpleStructure), retObject)
    Assert.AreEqual(input.MemberOne, DirectCast(retObject, SimpleStructure).MemberOne)
End Sub

Ian Horwill.. 5

使用原始样本,我同意它适用于C#但不适用于VB!如果使用Reflector或ILDasm,您将看到对Field.SetValue(target,...)的调用实际编译(在VB中)为:

field.SetValue(RuntimeHelpers.GetObjectValue(target), ...)

GetObjectValue"返回obj的盒装副本(如果它是值类;否则返回obj本身." 即值正在您的结构的副本上设置!

此链接给出了解释(例如它).解决方法是将target声明为System.ValueType而不是Object.我不确定这实际上是否对您的实际代码有帮助:您可能需要一个混乱的类型测试才能够与引用类型分开处理值类型.



1> Ian Horwill..:

使用原始样本,我同意它适用于C#但不适用于VB!如果使用Reflector或ILDasm,您将看到对Field.SetValue(target,...)的调用实际编译(在VB中)为:

field.SetValue(RuntimeHelpers.GetObjectValue(target), ...)

GetObjectValue"返回obj的盒装副本(如果它是值类;否则返回obj本身." 即值正在您的结构的副本上设置!

此链接给出了解释(例如它).解决方法是将target声明为System.ValueType而不是Object.我不确定这实际上是否对您的实际代码有帮助:您可能需要一个混乱的类型测试才能够与引用类型分开处理值类型.

推荐阅读
雨天是最美
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有