比如这样的
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
1 h82258652 2022-09-08 10:03:08 +08:00 编译之后拿 ILSpy 看一下呗。init 就是个语法糖,SetProperty 还是会生成的,就是多了个 Attribute 导致编译器让你编译报错。 |
2 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; } } |
3 bthulu OP @hervey0424 还真可以反射直接设值啊, 那这个 init 的意义何在? |
4 Mithril 2022-09-08 10:20:14 +08:00 你都已经反射了,直接给那个 Property 去 SetValue 就行了。 或者你搞个带参数的构造函数,直接调用那个构造函数就行。 |
5 reallittoma 2022-09-08 10:29:30 +08:00 @bthulu #3 一楼已经说了,init 的意义就是语法糖。 |
6 hervey0424 2022-09-08 11:20:50 +08:00 bthulu 用 init 就是表示怕你直接给他赋值, 如果你非要这么干, 可以反射 |
7 forgottencoast 2022-09-18 16:22:50 +08:00 这是一种设计思想,类型的设计者用 init 来向你传递一个意思: ta 不想你创建实例以后在来更改这个值,ta 认为这个值在这个实例的生命周期内应该是不变的(或者有其他复杂的规则)。 |