了解 C# 属性
C# 11(随 .NET 7 引入)为属性带来了一个令人兴奋的新增功能:required 关键字。 在本文中,我们将探讨 C# 属性,并使用 Tim Corey 的简洁视频教程" .NET 7 更新:10 分钟或更短时间内掌握必需属性"中的示例。 我们将从属性的基础知识讲解到新的 required 关键字,以及它如何帮助强制执行初始化规则。
C# 属性
在 C# 中,属性允许您封装字段并管理对对象类数据成员的访问。 它们通常用于在允许外部访问的同时确保数据完整性。 可以使用属性对私有字段进行封装,从而控制数据的访问或修改方式。 公共字符串属性通常使用称为访问器(get 和 set)的特殊方法来高效地操作类成员。 C# 中的静态属性无需实例化类即可访问,这为管理属性值提供了一种独特的方式。
以下是 Tim 如何设置一个简单的房产示例进行演示。
创建控制台应用程序
首先,Tim 使用 C# 11 开发了一个基本的 .NET 7 控制台应用程序。该版本引入了 required 关键字,而该关键字在以前的 .NET 版本中不可用。
定义一个简单的模型
Tim 创建了一个 PersonModel 类,其中包含用于 FirstName 和 LastName 的属性:
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}这些属性允许 PersonModel 存储名字和姓氏。 然而,如果没有额外的设置,FirstName 和 LastName 可能会未初始化,从而导致空值。
使用构造函数确保初始化
确保属性始终被初始化的常用方法是通过构造函数。 在 Tim 的示例中,他在 PersonModel 的基类中添加了一个构造函数,该构造函数需要同时提供 FirstName 和 LastName:
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}这种方法确保每当创建一个 PersonModel 对象时,必须提供 FirstName 和 LastName。 如果我们尝试在不指定这些值的情况下创建一个 PersonModel,编译器将标记为错误。
可空上下文
从 .NET 6 和 C# 10 开始,C# 引入了可为空引用类型。这意味着属性需要要么初始化,要么使用 ? 显式标记为可空。 例如,如果 FirstName 和 LastName 可以为空,我们将它们定义如下:
public string? FirstName { get; set; }
public string? LastName { get; set; }public string? FirstName { get; set; }
public string? LastName { get; set; }然而,在 Tim 的示例中,我们假设 FirstName 和 LastName 应始终非空。 最初,可空性是通过仔细初始化或可空注解来处理的,但从 C# 11 开始,我们有了更强大的选择。
引入所需的关键词
虽然构造函数可以强制初始化,C# 11 引入了 required 关键字,使特定属性的设置更容易。 使用 required,您可以将单个属性标记为必需,这意味着它们必须在对象初始化期间被赋值。
设置所需属性
为了使 FirstName 和 LastName 成为必需属性,Tim 在 4:15 修改了 PersonModel 类,如下所示:
public class PersonModel
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
}public class PersonModel
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
}通过使用 required 标记这些属性,编译器现在会强制它们通过对象初始化器或构造函数进行设置。 这样做的好处是,无需创建构造函数即可指定特定属性。
示例用法及所需属性
现在,我们可以如下创建并初始化 PersonModel:
PersonModel person = new() { FirstName = "Tim", LastName = "Corey" };PersonModel person = new() { FirstName = "Tim", LastName = "Corey" };如果我们省略 FirstName 或 LastName,编译器将标记为错误,提示我们初始化这些必需的属性。
使用构造函数需要
Tim 展示了一个同时使用 required 属性和构造函数的情况。 在构造函数设置必需属性的情况下,C# 需要确保在调用构造函数时这些属性仍然已初始化。
在这种情况下,可以使用 SetsRequiredMembers 特性来表明构造函数满足了所需条件。 以下是蒂姆的应用方法:
[SetsRequiredMembers]
public PersonModel()
{
FirstName = "Test";
LastName = "Test";
}
[SetsRequiredMembers]
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}[SetsRequiredMembers]
public PersonModel()
{
FirstName = "Test";
LastName = "Test";
}
[SetsRequiredMembers]
public PersonModel(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}添加 SetsRequiredMembers 告知编译器这些属性将在构造函数中设置,避免初始化错误。 此功能有助于防止意外遗漏,同时允许灵活地初始化属性。
为什么必需属性很有用
Tim 解释说,新的 required 关键字简化了确保属性始终设置的过程。 现在,我们无需在每种情况下都使用构造函数来设置方法,也无需冒着属性未设置的风险,而是可以直接在属性声明中要求特定值。
此功能在某些字段为必填项的数据模型中尤为突出,它可以通过防止运行时空值错误,帮助在开发过程早期发现问题。
其他属性示例
然后,Tim 添加了一个可选属性 Email,它可以为空:
public string? Email { get; set; }public string? Email { get; set; }因为它没有用 required 标记,所以 Email 属性可以不设置而不会导致编译器错误。 通过这个例子,蒂姆展示了这种做法赋予类很大的灵活性,它能够清晰地区分必要数据字段和可选数据字段。
结论
C# 11 中新增的必需属性对开发人员来说是一项很有价值的功能,它确保了必要的属性始终得到初始化。 Tim Corey 的视频对这一功能进行了很好的介绍,并演示了它在控制台应用程序中的工作原理。 通过将 required 关键字与对象初始化器和构造函数相结合,我们可以在 C# 中创建更健壮和更安全的数据模型。 如需更多内容丰富的教程,请访问 Tim 的YouTube 频道。

