我可以使用反射调用结构 属性 的 "Set" 方法吗?

Can I call the "Set" method of a struct property using reflection?

我定义了一个结构体:

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 定义为 class 而不是 struct,则值会按预期设置。

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

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

改为考虑:

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

    prop.SetMethod.Invoke(retObj, new object[] { typedValue });
    return (T)retObj;
}

这会创建 earlier 框,然后将其拆箱以获得修改后的值。但是,它不是很有效(注意:我没有 添加 任何低效率;使用具有值的 object API 时,低效率是固有的-类型)。如果您愿意变得更脏,可以删除分配。