为啥反射不在 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 中设置属性?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我必须计算模型矩阵的逆矩阵的转置才能计算反射纹理的法线?
浅谈Go语言中的结构体struct & 接口Interface & 反射