C# 我可以使用反射调用结构属性的“Set”方法吗?

C# 我可以使用反射调用结构属性的“Set”方法吗?,c#,.net,reflection,f#,system.reflection,C#,.net,Reflection,F#,System.reflection,我定义了一个结构: public struct Settable { public string SettableProperty { get; set; } } 我可以用通常的方式设置结构属性的值: s.SettableProperty = "Abc"; 但是,当我创建一个方法试图通过反射设置属性时: public T CreateWithValue<T>(string propName, string propValue) { var retObj = Ac

我定义了一个结构:

public struct Settable
{
     public string SettableProperty { get; set; }
}
我可以用通常的方式设置结构属性的值:

s.SettableProperty = "Abc";
但是,当我创建一个方法试图通过反射设置属性时:

public T CreateWithValue<T>(string propName, string propValue)
{
    var retObj = Activator.CreateInstance<T>();
    var prop = typeof(T).GetProperty(propName);

    var _ = prop.SetMethod.Invoke(retObj, new object[] { propValue});
    return retObj;
}
…并这样称呼它:

var x = CreateWithValue<Settable>("SettableProperty", "Abc");
…我最终将SettableProperty初始化为其默认值null。没有抛出异常

请注意,如果我将Settable定义为类而不是结构,则该值将按预期设置

是否可以使用反射设置结构属性?

这里的问题是retObj是T,一种值类型,但Invoke接受对象。这将装箱该值,该值在箱子内的堆上创建一个独立副本,然后对其进行变异。您在retObj中的本地副本在这里不会受到任何影响,因为它是值的完全断开连接的副本

相反,请考虑:

public T CreateWithValuestring propName、string propValue { object retObj=Activator.CreateInstance; var prop=typeofT.GetPropertypropName; prop.SetMethod.InvokeretObj,新对象[]{typedValue}; 返回TretObj; } 这会更早地创建该框,并取消其装箱以获得修改后的值。然而,这并不是很有效率:我没有增加任何低效率;当使用具有值类型的对象API时,效率低下是固有的。如果您很高兴得到更脏的东西,您可以删除分配。

这里的问题是retObj是T,一种值类型,但Invoke接受对象。这将装箱该值,该值在箱子内的堆上创建一个独立副本,然后对其进行变异。您在retObj中的本地副本在这里不会受到任何影响,因为它是值的完全断开连接的副本

相反,请考虑:

public T CreateWithValuestring propName、string propValue { object retObj=Activator.CreateInstance; var prop=typeofT.GetPropertypropName; prop.SetMethod.InvokeretObj,新对象[]{typedValue}; 返回TretObj; }
这会更早地创建该框,并取消其装箱以获得修改后的值。然而,这并不是很有效率:我没有增加任何低效率;当使用具有值类型的对象API时,效率低下是固有的。如果您很高兴变得更脏,您可以删除分配。

附带说明:拥有可变结构通常是一个糟糕的想法;如果我对此有投票权,我强烈建议使用public readonly struct Settable和通过构造函数设置的get-only属性。@marcgravel-noted。这是一段测试代码,我最终将得到许多我希望能够轻松进行值比较的结构,Assert.AreEqual可以使用这些结构。我还希望使它们能够灵活地进行测试。您是否建议将它们设置为类并使用不同的比较方法,或者这似乎是使用可变结构的合理时间;我所知道的是,我帮助了很多人与可变结构抗争——他们造成了很多混乱。嗯,花了5个小时,但我遇到了与可变结构相关的问题。接受建议。但想想你在这个过程中学到了多少!玻璃杯半满,等等,附带说明:拥有一个可变结构通常是一个糟糕的想法;如果我对此有投票权,我强烈建议使用public readonly struct Settable和通过构造函数设置的get-only属性。@marcgravel-noted。这是一段测试代码,我最终将得到许多我希望能够轻松进行值比较的结构,Assert.AreEqual可以使用这些结构。我还希望使它们能够灵活地进行测试。您是否建议将它们设置为类并使用不同的比较方法,或者这似乎是使用可变结构的合理时间;我所知道的是,我帮助了很多人与可变结构抗争——他们造成了很多混乱。嗯,花了5个小时,但我遇到了与可变结构相关的问题。接受建议。但想想你在这个过程中学到了多少!半满的玻璃杯等