使用反射初始化不可变类

问题描述 投票:1回答:1

我有一个具有只读属性的类。我尝试不向其添加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。我主要是在寻找一种获取构造函数的方法,按名称循环遍历其参数,并根据需要对输入进行排序。

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

c# serialization reflection
1个回答
3
投票

这里,序列化程序通常使用两种方法;首先是通过查看构造函数将其识别为元组模式。这很笨拙,但很容易实现只要名称和类型完全匹配-只需查看Type.GetConstructors()并查看所有顺序即可。

但是,也许是使用罗斯林的知识。如果我们compile your code,我们将看到:

[CompilerGenerated] private readonly decimal <Price>k__BackingField; [CompilerGenerated] private readonly string <Name>k__BackingField;

<{property name}>k__BackingField的这种模式非常可靠,并被编码为Rosyln。实际上,更改的可能性很小,并且在

很多情况]下都可以很好地工作。许多序列化程序都在寻找这些,并使用非公共反射来设置字段。有些还通过FormatterServices.GetUninitializedObject通过对象[对象不调用构造函数[对于SomeProperty,其他常见模式包括-称为someProperty_somePropertym_someProperty的私有字段,或使用属性来修饰事物的更明确的方法。

© www.soinside.com 2019 - 2024. All rights reserved.