繁体   English   中英

我可以使用反射调用结构属性的“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 这将值起来,这会在堆(框内)上创建一个隔离副本,然后您对其进行变异。 您在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;
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM