为啥反射不在 Struct 中设置属性?

Posted

技术标签:

【中文标题】为啥反射不在 Struct 中设置属性?【英文标题】:Why doesn't reflection set a property in a Struct?为什么反射不在 Struct 中设置属性? 【发布时间】:2011-09-30 07:18:05 【问题描述】:
   class PriceClass 

        private int value;
        public int Value
        
            get  return this.value; 
            set  this.value = value; 
                   
    


    struct PriceStruct
    

        private int value;
        public int Value
        
            get  return this.value; 
            set  this.value = value; 
        
    
    static void Main(string[] args)
    
        PriceClass _priceClass = new PriceClass();
        Type type = typeof(PriceClass);
        PropertyInfo info = type.GetProperty("Value");
        info.SetValue(_priceClass, 32, null);
        Console.WriteLine(_priceClass.Value);

        PriceStruct _priceStruct = new PriceStruct();
        type = typeof(PriceStruct);
        info = type.GetProperty("Value");
        info.SetValue(_priceStruct, 32, null);
        Console.WriteLine(_priceStruct.Value);

        Debugger.Break();
    

打印的第一个值是 32,第二个是 0。没有抛出异常

【问题讨论】:

查看这个问题的公认答案:***.com/questions/6280506/… 【参考方案1】:

这是因为装箱你的结构会复制它,所以你应该更早地装箱,这样你就可以从你修改过的相同数据中调用 getter。以下代码有效:

    object _priceStruct = new PriceStruct(); //Box first
    type = typeof(PriceStruct);
    info = type.GetProperty("Value");
    info.SetValue(_priceStruct, 32, null);
    Console.WriteLine(((PriceStruct)_priceStruct).Value); //now unbox and get value

    Debugger.Break();

【讨论】:

谢谢。这是我第一次看到强制装箱(将结构转换为对象)和拆箱(将对象转回结构)以查看正在发生的事情并了解该过程。这很简单,真的。但是在我看到的其他任何地方,装箱步骤都是由隐藏进程完成的(由编译器自动完成),并且如何使用它是没有意义的。【参考方案2】:

structs 是 ValueTypes,它是按值传递的,这意味着你只传递整个 struct 的副本,而不是对原始对象的引用。

所以当你将它传递给info.SetValue(_priceStruct, 32, null) 时,copy 会被传递给该方法并发生变异,因此原始对象根本不会改变。可变结构是邪恶的另一个原因。

【讨论】:

【参考方案3】:

您仍然可以使用反射来更改它们,但它有点冗长。

请参阅此示例:http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/2dd4315c-0d0d-405c-8d52-b4b176997472

【讨论】:

+1 你的例子表明我认为可以做到最好。在“安全”代码中,不可能使用反射来更改真正值类型中的字段,但是对于每种值类型,都有一个对应的装箱类类型。转换为具有讽刺意味的 ValueType 会将值类型转换为其对应的装箱类类型的实例,然后可以使用反射对其进行变异;突变后,装箱实例的内容可以复制回真正的值类型对象。

以上是关于为啥反射不在 Struct 中设置属性?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须计算模型矩阵的逆矩阵的转置才能计算反射纹理的法线?

Golang 接口与反射知识要点

浅谈Go语言中的结构体struct & 接口Interface & 反射

反射与annotation

Linq WHERE EF.Functions.Like - 为啥直接属性起作用而反射不起作用?

为啥反射type.GetFields 取不到任何值