禁用可为空的目标是什么,我们将来禁用时如何使用它?



由于C#10,Nullable在默认情况下将被禁用

我已经看到了很多关于Nullable的文章和视频,他们只是说我们不再担心Null引用异常

他们还说有很多方法可以使用它:DisableEnableWarningAnnotations。。。。。布拉布拉。

介绍了?.????=NotNullWhenTrueNotNullWhenFalse。。。etc

但我没有看到任何人告诉我们:当它禁用时如何使用

我们以前有很多场景需要使用null

1.属性:

// What is the default value when nullable disabled , and how way we should use it?
Public string Name { get; set; } 

2.林克:

Person model = PersenList.Where(x => x.id == id).FirstOrDefault();
if (null != model)
{
// Do something
}
// How should we do when nullable diabled, what is the default value now, and how way we could check it a default value or not?

3.临时变量:

string ageDescription = null;
if (student.Age > 13)
{
ageDescription = "X";
}
if (student.Age > 15)
{
ageDescription = "XL";
}
if (student.Age > 18)
{
ageDescription = "XXL";
}
System.Diagnostics.Debug.WriteLine($"The Student size: {(ageDescription ?? "Not found")}");
// What should we do in this case, bring "Not found" at the began always?

string description = null;
if (student.Score < 70)
{
description = "C";
}
if (student.Score > 70)
{
description = "B";
}
if (student.Score > 80)
{
description = "A";
}
if (student.Score > 90)
{
description = "AA";
}
student.description = description;
JsonConvert.Serialize(student, {with Ignore Null Option for save more space});
// How do we save the json size and space, if we disable the nullable?

string value = null;
try {
value = DoSomething();
if (value == "Something1")
{
Go1();
}
if (value == "Something2")
{
Go2();
}
if (value == "Something3")
{
Go3();
}
} catch (Exception ex)
{
if (null == value)
{
GoNull();
}
else
{
GoOtherButException(ex)
}
}
// How should we handle this kind of problem?

4.实体框架

//The tables always has null field and how we deal with it when nullable disabled?

我知道我们可能会处理更多的情况。我觉得他们只是在虚张声势,有这么多可为null的功能太棒了,但没有给我们任何方向或好的方法来指出。

我希望有人已经使用了C#10,向我们指出在禁用Nullable后如何改变我们老式的代码样式,并给我们一些例子来向我们展示我们将来应该如何做。感谢

--------更新1-------

我添加了一些可变的例子。

--------更新2--------有些家伙说我们可以随心所欲。这是基于你的要求。如果你想使用它,只需简单地添加?,比如:

string? name = null

但我更希望他们能告诉我:在每个地方都用String.Empty代替null。哈哈。。。。

但在这种情况下,每个地方我仍然需要检查if ( variable != String.Empty),但我们可以避免空引用异常,我也不确定String.Empty会占用内存中的多少空间。

那么,为什么没有人告诉我们这样做呢:当他们告诉我们禁用nullable时,我们需要如何改变我们的代码样式

另一件事是,我真的不明白,在我们总是使用if (null != model)之前,我们如何在使用FirstOrDefault()时检查Linq的默认值。

也许我真的想知道:如果我们都禁用了可为null的,那么未来的世界会是什么样子。

我觉得需要澄清的第一件事是,启用可为null的引用类型不会影响代码是否可以构建。它对默认值没有影响。

可为null的引用类型旨在使您能够使用Express your design intent more clearly with nullable and non-nullable reference types。这是很棒的教程的标题:可以为null的引用类型,我强烈建议任何试图深入研究这一功能的人阅读它

可为null的引用类型特性允许您显式声明:我从不希望这个(可为null类型)属性是未知的。因此,它应该总是有价值的。

若要声明您希望属性始终具有值,请将其定义为常规

public string Text { get; set; }

若要明确声明某个属性不一定具有值,将使用"?"进行定义类型之后

public string? Text { get; set; }

希望这个功能的意图现在或多或少已经清楚了。让我们深入探讨你的具体问题。

1.属性:

您的问题:

// What is the default value when nullable disabled , and how way we should use it?
public string Name { get; set; } 

未初始化的字符串或类属性仍将为null。没有显式初始化的int仍然为0,没有显式初始化的boolean仍然默认为false。为了不重复关于如何使用它的相同文本,我只重复这一点。您应该将其用于Express your design intent more clearly with nullable and non-nullable reference types。由您来标记解决方案中的所有类,以确定属性是否具有此特性。不,这样做不好玩。但你也不需要一次完成。您可以很容易地启用该功能(有大量警告),并稳步迈向一个或多或少包含所有类的解决方案。

2.林克:

Person model = PersonList.Where(x => x.id == id).FirstOrDefault();
// How should we do when nullable diabled, what is the default value now, and how way we could check it a default value or not?

如果你有一个Linq查询,你不确定你是否真的能找到你想要的东西(很多情况下都是这样),.FirstOrDefault()仍然可以使用。但是Person model应该通过将其更改为Person? model来表示它可能为空。

3.临时变量:

你想让一个临时变量一开始为null,然后有条件地赋值吗?没问题,只要加上魔法"?">

或者!如果你确定要给它一个值,为什么不给它赋值呢?例如:

string description = string.Empty;
if (student.Score < 70)
description = "C";
// ... some more conditions ...
student.description = description;

4.实体框架

我认为,在数据访问层中,将非常清楚地标记哪些属性永远不会为空,哪些属性可能为空。只需查看数据库模型和查询/存储过程,以及在写入数据库之前所做的null检查。数据库中不能为null的所有内容都将在数据模型类中,并且可能包含的所有内容将标记为"?"在数据模型类中的类型之后。

如果启用了可为null的引用类型,世界会是什么样子

IDE将向您显示潜在意外null的警告。如果团队努力减少警告,这将导致属性明确说明它们是否为null。这是通过添加一个"属性类型之后。如果你确定某个东西不是空的,你可以添加一个"以抑制警告。

对于DTO类"是经常使用的东西。这是由于DTO类必须有一个空构造函数,并且其属性可以使用set;init;属性进行设置。将显示警告。在这里,可以为文件禁用警告,或者可以用默认值(可以为null)初始化属性,并使用"&";。对于这两种方式,在使用它们之前,属性都应该是空保护的。

通过使用":

public List<string> Comments { get; set; } = null!;

一个常见的现象是,你很可能会看到空保护子句减少。如果您确信所调用的代码保证符合可为null的引用类型功能,则可以执行此操作。值得注意的是,这些属性可能仍然为null,因此您可以打开null引用异常,而不是参数null异常。尽管如此,在我看来,这是值得澄清和缩小规模的。但每个人都有自己的看法。堆栈溢出问题:启用了可为null的引用类型的何时为null检查参数

最终的结果是,您的代码将清楚地表达预期的变量,因此应该以可为null的方式处理,有时不存在。如果可能的话,这可能会导致更少的保护条款,并带来更少(样板)代码的好处

参考

我真的希望我能帮你一点忙。如果你对教程之外的知识有更多的渴望,这里有一些关于可为null的引用类型的真正好的文档:

  • 教程:可为null的引用类型
  • 使用可为null的引用类型
  • 可为null的引用类型

最新更新