C# 9 中新加入的关键词 init,record,with

1. init 关键词

1.1 简介

在C# 9中,加入了一个新的关键词 init,它可以用来定义只读属性的初始化器。通常情况下,只读属性只能在构造函数中初始化,一旦初始化后就不能再更改。但是使用 init 关键词后,只读属性的值可以在对象初始化后通过 with 表达式进行修改。

1.2 使用 init 关键词定义只读属性

在定义只读属性时,可以使用 init 关键词代替 get 访问器:

public class Person

{

public string Name { get; init; }

public Person(string name)

{

Name = name;

}

}

在上面的例子中,Name 属性在初始化后就不能再更改。如果要修改属性的值,可以使用 with 表达式:

Person person = new Person("Alice");

person = person with { Name = "Bob" };

Console.WriteLine(person.Name); // 输出 "Bob"

1.3 init 关键词与构造函数

当一个类同时包含 init 关键词和构造函数时,构造函数可以初始化 init 关键词修饰的属性:

public class Person

{

public string Name { get; init; }

public int Age { get; init; }

public Person(string name, int age)

{

Name = name;

Age = age;

}

}

在上面的例子中,构造函数可以设置 Name 和 Age 属性的初始值。之后,这些属性的值也可以通过 with 表达式进行修改。

2. record 关键词

2.1 简介

另一个在C# 9中引入的关键词是 record。record 可以用来创建不可变的数据类型,其属性默认都是只读的。

2.2 使用 record 关键词创建类型

通过使用 record 关键词,可以很方便地创建一个不可变的数据类型:

public record Person(string Name, int Age);

Person person1 = new Person("Alice", 30);

Person person2 = new Person("Alice", 30);

Console.WriteLine(person1 == person2); // 输出 "True"

在上面的例子中,person1 和 person2 的值是相等的,因为它们具有相同的属性值。record 类型的实例是通过值来比较的,而不是引用。

2.3 record 类型的 with 表达式

与 init 关键词一样,record 类型的实例也可以通过 with 表达式进行属性的修改。与普通类型不同的是,with 表达式返回的是一个新的 record 对象,原始对象的值不会改变。

Person person = new Person("Alice", 30);

Person newPerson = person with { Age = 40 };

Console.WriteLine(newPerson); // 输出 "Person { Name = Alice, Age = 40 }"

Console.WriteLine(person); // 输出 "Person { Name = Alice, Age = 30 }"

如上所示,通过 with 表达式修改 Age 属性后,返回的是一个新的 Person 对象,原始对象的值保持不变。

3. with 表达式

3.1 简介

除了用于修改 record 类型的属性外,with 表达式还可以用于其他类的实例,但前提是这些类的属性都是只读的。

3.2 使用 with 表达式修改属性

通过 with 表达式,可以方便地创建一个新的对象,并修改其中的属性值:

public class Person

{

public string Name { get; init; }

public int Age { get; init; }

}

Person person = new Person { Name = "Alice", Age = 30 };

Person newPerson = person with { Age = 40 };

Console.WriteLine(newPerson); // 输出 "Person { Name = Alice, Age = 40 }"

Console.WriteLine(person); // 输出 "Person { Name = Alice, Age = 30 }"

上述代码中,通过 with 表达式修改了 newPerson 对象的 Age 属性,而原始对象 person 的值保持不变。

3.3 with 表达式的链式调用

如果一个类的多个属性需要进行修改,可以通过链式调用多个 with 表达式来实现:

Person person = new Person { Name = "Alice", Age = 30 };

Person newPerson = person with { Age = 40 } with { Name = "Bob" };

Console.WriteLine(newPerson); // 输出 "Person { Name = Bob, Age = 40 }"

上述代码中,首先使用 with 表达式修改了 newPerson 对象的 Age 属性,然后再用另一个 with 表达式修改了其 Name 属性。

总结

在C# 9中,引入了三个新的关键词:init、record和with。init 关键词用于定义只读属性的初始化器,可以通过 with 表达式进行修改;record 关键词用于创建不可变的数据类型,属性默认都是只读的,可以通过 with 表达式进行修改;with 表达式用于修改只读属性的值,返回一个新的对象。

这些新的关键词使得代码编写更加简洁和易于理解,提高了代码的可读性和可维护性。它们在代码重构和状态管理方面也有很大的帮助。因此,熟练掌握这些新特性将有助于开发人员更好地利用C# 9的新功能。

后端开发标签