【问题标题】: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。没有抛出异常

【问题讨论】:

标签: reflection c#-4.0 struct properties


【解决方案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 会将值类型转换为其对应的装箱类类型的实例,然后可以使用反射对其进行变异;突变后,装箱实例的内容可以复制回真正的值类型对象。
    猜你喜欢
    • 2013-01-16
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多