gpt4 book ai didi

c# - 使用反射初始化不可变类

转载 作者:太空宇宙 更新时间:2023-11-03 22:29:57 26 4
gpt4 key购买 nike

我有一个具有只读属性的类。我试图不向它添加 setter ,并且希望它可以使用正确的值创建并且之后永远不会更改。

public class Stuff 
{
public decimal Price { get; }
public string Name { get; }
public Stuff(decimal price, string name)
{
Price = price;
Name = name;
}
}

问题是我可能还有几个这种性质的不同类。我希望能够将属性从一种文本格式映射到实际对象。但是我不能使用反射来访问属性的 set 方法,因为没有。

这留下了获取构造函数并调用它的选项。那太好了,但我没有看到一个可靠的方法来检索构造函数。我看到最好的方法是传入一个类型数组来获取特定的构造函数。

var props = typeof(T).GetProperties().Select(p => p.PropertyType).ToArray();
var constructor = typeof(T).GetConstructor(props);

根据属性的顺序,以上可能会返回 null。我主要是在寻找一种方法来获取构造函数,按名称循环遍历其参数,并根据需要对我的输入进行排序。

我知道框架支持序列化和反序列化这些类型的类,所以它一定是可能的。我只是不确定它是如何完成的。

最佳答案

这里有两种序列化器常用的方法;首先是通过查看构造函数将其识别为元组模式。这既笨拙又脆弱,但只要名称和类型完全匹配就可以完美实现 - 看看Type.GetConstructors()并查看所有订单。

不过,也许更常见是使用 Roslyn 的知识。

如果我们 compile your code ,我们看到:

    [CompilerGenerated]
private readonly decimal <Price>k__BackingField;

[CompilerGenerated]
private readonly string <Name>k__BackingField;

<{property name}>k__BackingField 的这种模式非常可靠,已编码到 Rosyln 中。实际上,它不太可能改变,并且在许多情况下 都运行良好。许多序列化器寻找这个并使用非公共(public)反射来设置字段。有些还创建对象而不调用构造函数,通过FormatterServices.GetUninitializedObject .

其他常见模式包括,对于 SomeProperty - 名为 someProperty 的私有(private)字段, _someProperty , m_someProperty ,或使用属性来装饰事物的更明确的方法。

关于c# - 使用反射初始化不可变类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58400999/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com