zoukankan      html  css  js  c++  java
  • C# 反射结构体struct的一个坑

    今天代码用到了反射赋值,代码是这样写的:

    1 var objtype = obj.GetType();
    2 var Fieldinfo = objtype.GetField("I64");
    3 Fieldinfo.SetValue(obj, 100L);

    当用户传进来的obj是class的时候无问题.但是传进来struct的时候,即不报错也不提示,但却什么值都没赋上!

    经过多番查询.直到看到这个关于struct和class的区别:

    http://www.cnblogs.com/gsk99/archive/2011/05/20/1904552.html

    和这个装箱/拆箱的说明:

    http://www.cnblogs.com/huashanlin/archive/2007/05/16/749359.html

    其中有一段:

    6:装箱/拆箱的内部操作。 
    装箱: 
    对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行。 
    第一步:新分配托管堆内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。 
    第二步:将值类型的实例字段拷贝到新分配的内存中。 
    第三步:返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。 
    有人这样理解:如果将Int32装箱,返回的地址,指向的就是一个Int32。我认为也不是不能这样理解,但这确实又有问题,一来它不全面,二来指向Int32并没说出它的实质(在托管堆中)。 
    拆箱:
    检查对象实例,确保它是给定值类型的一个装箱值。将该值从实例复制到值类型变量中。 
    有书上讲,拆箱只是获取引用对象中指向值类型部分的指针,而内容拷贝则是赋值语句之触发。我觉得这并不要紧。最关键的是检查对象实例的本质,拆箱和装箱的类型必需匹配,这一点上,在IL层上,看不出原理何在,我的猜测,或许是调用了类似GetType之类的方法来取出类型进行匹配(因为需要严格匹配)。

    我看了看我调用的:SetValue方法.第一个参数是个object,是引用类型,也就是说,当我调用的时候,其实net把我的struct复制了一份,然后在新的那份改了值,我这边这份当然是没有被动过的.

    原因找到了,解决也就不难了,解决方案1:

    在调用SetValue之前,就把我的struct转成object,然后调用完再转回来:

     1     public struct MyStruct
     2     {
     3         public int TestInt;
     4     }
     5 
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             var Mystruct = new MyStruct();
    11             Type myType = typeof(MyStruct);
    12             FieldInfo myFieldInfo = myType.GetField("TestInt");
    13             Object someBoxedStruct = Mystruct;
    14             myFieldInfo.SetValue(someBoxedStruct, 1);
    15             MyStruct someUnBoxedStruct = (MyStruct)someBoxedStruct;
    16         }
    17    }

    尝试了一下,是可以的.

    还有一种方法,偶然搜索到的,把写入那部分改成这样:

    1 FieldInfo fi = typeof(T).GetField(name, BindingFlags.Public | BindingFlags.Instance);
    2 TypedReference reference = __makeref(obj);
    3 fi.SetValueDirect(reference, x);

    也是可以的.

  • 相关阅读:
    83. Remove Duplicates from Sorted List
    35. Search Insert Position
    96. Unique Binary Search Trees
    94. Binary Tree Inorder Traversal
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    111. Minimum Depth of Binary Tree
    169. Majority Element
    171. Excel Sheet Column Number
    190. Reverse Bits
  • 原文地址:https://www.cnblogs.com/DragonStart/p/7482627.html
Copyright © 2011-2022 走看看