.NET8 中空引用处理以及DDD相关概念
作为一名.NET开发者,小白很开心看到.NET版本更新后,.NET语法越来越有意思,写起来也越来越有趣。
很多新的语法,虽然变化不小,但是对小白这位从.NET Framework就开始写.NET的程序员来说,那也是信手拈来。
但是小白发现string都开始变为可空的时候,那还是认真的翻阅了一下相关的资料,以免不了解相关细节而写出漏洞百出或很低效的代码。
下面是小白整理的关于.NET8中的空引用处理
第一点
在 .NET 8 中,可以使用 C# 8 引入的 null 安全性功能来处理可能的 null 引用赋值。这些功能旨在帮助开发人员更好地处理可能为空的引用,并减少空引用异常的风险。
以下是在 .NET 8 中处理可能的 null 引用赋值的一些常用方法:
1. 使用可空引用类型(nullable reference types):在 .NET 8 中,可以使用 `?` 运算符将引用类型标记为可空。这样做可以告诉编译器该引用类型可为空,并且需要进行 null 检查。例如:
```csharp
string? nullableString = null; // 可空引用类型
string nonNullableString = "Hello";
int length = nullableString?.Length ?? 0; // 使用 null 条件运算符和 null 合并运算符处理可能的 null 引用赋值
int length2 = nonNullableString.Length; // 非空引用类型,不需要进行 null 检查
```
2. 使用非空断言运算符(non-null assertion operator):在某些情况下,您可能确定一个引用不会为空,并且希望告诉编译器不进行 null 检查。您可以使用 `!` 运算符,称为非空断言运算符。
但是请谨慎使用,因为如果该引用为空,将会引发 `NullReferenceException`。例如:
```csharp
string? nullableString = null;
int length = nullableString!.Length; // 使用非空断言运算符告诉编译器不进行 null 检查
```
3. 使用 null 合并运算符(null coalescing operator):您可以使用 `??` 运算符来处理可能的 null 引用赋值,并指定一个默认值。如果值不为空,则使用该值;如果值为空,则使用默认值。例如:
```csharp
string? nullableString = null;
string nonNullableString = "Hello";
string result = nullableString ?? nonNullableString; // 使用 null 合并运算符处理可能的 null 引用赋值
```
以上是在 .NET 8 中处理可能的 null 引用赋值的一些方法。这些功能旨在帮助开发人员更好地处理可能为空的引用,并在编译时提供更多的安全性。请根据您的具体需求和代码逻辑来选择合适的方法。
第二点:
在 .NET 8 中,引用类型默认情况下是不可空的。这意味着如果您定义一个引用类型的变量,它默认情况下是不允许赋值为 null 的。
这是通过引入 C# 8 中的可空引用类型(nullable reference types)特性实现的。 然而,通过在类型声明后面添加 `?` 运算符,您可以将引用类型标记为可空。这样一来,在可空引用类型中使用变量时,
编译器会要求您进行 null 检查,以防止 null 引用异常。
在之前的版本中,引用类型默认情况下是可空的,这意味着您可以将任何引用类型的变量赋值为 null。这导致了隐式的 null 引用异常风险,因为开发人员可能忘记在使用引用类型之前进行 null 检查。
在 .NET 8 中,引入可空引用类型的目的是强制开发人员更加谨慎地处理可能为空的引用,从而减少空引用异常的发生。
虽然这增加了一些额外的代码判断,但也提高了代码的安全性和可靠性。 因此,在 .NET 8 中,建议根据需要显式地标记引用类型为可空或非可空,并根据情况进行 null 检查。
这可以通过在声明引用类型时使用 `?` 运算符来标记为可空引用类型,或者在使用可空引用类型时使用 null 条件运算符 `?.` 或 null 合并运算符 `??` 进行 null 检查。这样可以更好地处理潜在的 null 引用异常。
虽然,大部分内容对于.NET开发者来说并不陌生,但是应用类型可空和非空断言运算符,还是需要好好了解一下的!
初次之外,面向领域编程,对于小白来说即新颖又高端,而且很分布式,所以小白整理了一些DDD相关的知识,以及在DDD模式下一些常用的模块库
1.DDD的相关概念
聚合根:
聚合根(Aggregate Root)是领域驱动设计(DDD)中的一个重要概念,它代表一个聚合对象的根实体,其他子实体和值对象都是以该根实体为基础而存在的。
简单来说,聚合根就是整个聚合对象中的最外层对象,是整个聚合对象的唯一访问入口。
通过聚合根可以确保整个聚合对象的一致性和完整性,并且也提供了一个清晰的边界,使得不同聚合之间的关系可以更加清晰地定义。
在开发过程中,我们通常会先确定聚合根,然后再根据实际需要向该聚合根中添加子实体或值对象。
聚合对象:
聚合对象(Aggregate)是领域驱动设计(DDD)中的一个概念,表示一组相关的对象以及它们之间的关系。
聚合对象是由聚合根(Aggregate Root)和其包含的子实体(Entity)和值对象(Value Object)组成的。
聚合对象是为了实现数据一致性、完整性和业务规则的封装,它定义了一系列相关对象的边界,并且确保这些对象按照一定的规则进行管理和操作。
聚合对象内部的对象之间具有强一致性,外部对象只能通过聚合根进行访问和修改。
聚合对象的设计应该尽量遵循聚合根负责保护内部对象一致性的原则,尽量减少外部对象对聚合内部对象的直接访问和操作。
通过聚合对象的概念,可以更好地组织和管理复杂的业务逻辑,并且提高系统的可维护性和可扩展性。
2.MediatR-中介者消息传递和处理
MediatR 是一个在 .NET 平台上流行的开源中介者模式库,它提供了一种简洁高效的方式来处理应用程序中的消息传递和请求处理。
中介者模式是一种行为设计模式,它通过将系统中的请求发送者和接收者解耦,使得它们不需要直接相互通信,而是通过中介者来进行消息传递和处理。这种解耦可以减少组件之间的依赖关系,提高代码的灵活性和可维护性。
在 MediatR 中,消息被封装为对象,称为请求(Request)。请求可以通过中介者(Mediator)发送给一个或多个处理程序(Handler),处理程序根据请求的类型进行相应的处理,并返回结果。中介者负责分发请求并确保每个请求都被正确地路由到对应的处理程序。
使用 MediatR 的主要优点是简化代码结构,将请求处理逻辑集中到一个地方,提高代码的可读性和可测试性。它还提供了一些扩展功能,如管道(Pipeline)、通知(Notification)和命令-查询分离(CQS),使得应用程序的开发过程更加灵活和高效。
总结来说,MediatR 是一个帮助开发者实现中介者模式的库,它简化了消息的传递和处理,提高了代码的可读性和可测试性。通过使用 MediatR,开发者可以更好地组织和管理应用程序的逻辑,并减少组件之间的直接依赖关系。
它适用于各种类型的应用程序,包括 Web 应用、桌面应用和服务端应用等。
3.CAP-事件消息的发布和订阅
CAP 是一个基于 .NET Standard 的 C# 库,它是一种处理分布式事务的解决方案,同样具有事件总线(EventBus)的功能,它具有轻量级、易使用、高性能等特点。
在我们构建 SOA 或者 微服务系统的过程中,我们通常需要使用事件来对各个服务进行集成,在这过程中简单的使用消息队列并不能保证数据的最终一致性,
CAP 采用的是和当前数据库集成的本地消息表的方案来解决在分布式系统互相调用的各个环节可能出现的异常,它能够保证任何情况下事件消息都是不会丢失的。
你同样可以把 CAP 当做 EventBus 来使用,CAP提供了一种更加简单的方式来实现事件消息的发布和订阅,在订阅以及发布的过程中,你不需要继承或实现任何接口。