请教个问题, .net core 中, 带 init 属性的对象怎么通过反射创建赋值呢?

2022-09-08 09:54:16 +08:00
 bthulu

比如这样的

public class Student
{
    public int Id { get; init; }
}

如何通过反射创建 Student 并给 Id 赋值呢?

Student instance = Activator.CreateInstance<Student>()!;
// 上面这条语句已经将 Student 创建好了, 再调下面这条语句赋值就会报编译错误了
instance.Id = 22;

通过 json 反序列化得知是可以做到的, 就是不知道代码该怎么写

        var s = JsonSerializer.Deserialize<Student>("{\"Id\":22}")!;
        Console.WriteLine(s.Id); // 打印出了 22
1008 次点击
所在节点    问与答
7 条回复
h82258652
2022-09-08 10:03:08 +08:00
编译之后拿 ILSpy 看一下呗。init 就是个语法糖,SetProperty 还是会生成的,就是多了个 Attribute 导致编译器让你编译报错。
hervey0424
2022-09-08 10:09:03 +08:00
void Main()
{
Student instance = Activator.CreateInstance<Student>()!;
var idProperty = instance.GetType().GetProperty("Id");
idProperty.SetValue(instance, 22);
instance.Dump();
}

public class Student
{
public int Id { get; init; }
}
bthulu
2022-09-08 10:19:12 +08:00
@hervey0424 还真可以反射直接设值啊, 那这个 init 的意义何在?
Mithril
2022-09-08 10:20:14 +08:00
你都已经反射了,直接给那个 Property 去 SetValue 就行了。
或者你搞个带参数的构造函数,直接调用那个构造函数就行。
reallittoma
2022-09-08 10:29:30 +08:00
@bthulu #3 一楼已经说了,init 的意义就是语法糖。
hervey0424
2022-09-08 11:20:50 +08:00
@bthulu 用 init 就是表示怕你直接给他赋值, 如果你非要这么干, 可以反射
forgottencoast
2022-09-18 16:22:50 +08:00
这是一种设计思想,类型的设计者用 init 来向你传递一个意思:
ta 不想你创建实例以后在来更改这个值,ta 认为这个值在这个实例的生命周期内应该是不变的(或者有其他复杂的规则)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/878540

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX