比如这样的
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 认为这个值在这个实例的生命周期内应该是不变的(或者有其他复杂的规则)。 |