c# - 不使用 Setter 设置实例的属性
问题描述
假设我有一个类和一个如下所示的接口:
[Serializable]
public class MyClass : IClass
{
public int Prop => 42;
}
public interface IClass
{
int Prop { get; }
}
如您所见,没有 Setter。但我希望使用反射来改变 Prop 属性,但我似乎做不到。这是我到目前为止所拥有的:
var property = typeof(MyClass).GetProperty("Prop", BindingFlags.Instance | BindingFlags.Public);
property.SetValue(instaneOfClass, 31);
我不断收到此错误:System.ArgumentException: Property set method not found.
这不应该工作吗?如何在不使用 setter 的情况下设置属性?
解决方案
自动实现的属性具有名为<PropName>k__BackingField
.
在您的情况下,您将像这样访问此支持字段:
var property = typeof(MyClass).GetField("<Prop>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
property.SetValue(instanceOfClass, 31);
请注意,由于支持字段是私有的,所以我调用GetField()
而不是GetProperty()
,并使用BindingFlags.NonPublic
而不是。BindingFlags.Public
但是,由于这是一个表达式主体成员(lambda 语法),因此不会生成支持字段。getter 不依赖另一个成员,而是简单地返回给定表达式的结果,编译器不需要生成支持字段。
使用显式 getter 实现您的属性将生成一个支持字段,并且上面的代码将起作用。
public class MyClass : IClass
{
public int Prop { get; } = 42;
}
推荐阅读
- ms-access - 有没有办法防止onedrive在两台电脑之间同步时重命名我的访问数据库
- javascript - 自定义右键单击锚标记以在新选项卡中打开链接
- arrays - 使用 int 值数组,如何创建一个从数组中的每个 int 值开始倒计时的计时器?(迅速)
- html - 摘要标签显示“详细信息”而不是文本
- c++ - 没有匹配的函数来调用“strlen”
- visual-studio-code - 是否有键盘快捷键可以在 Visual Studio 代码中仅在一行中选择单词出现
- mysql - 如何根据分页 API 中的属性获取前 X 个项目?
- ethereum - 如何从 Geth 中的 eth_call 或 debug_traceCall 获取事件日志?
- batch-file - 在批处理脚本中从 Epic Games 启动游戏的问题
- python - 使用 python 创建一个套接字服务器,并从另一个网络\国家访问它