我经常偶然发现带有Empty属性的类,该属性表示未知或不知何故丢失的值。为什么不使用null?有没有什么好的实际理由让类有一个空的单例?或者一个结构,因为在这种情况下我们可以使用一个可以为null的属性。
澄清:我的意思不是说我应该使用现有的类似Empty的属性还是null,而是如果/何时我应该为我自己实现的新类添加Empty属性。
更新:
我想我只是混淆了编码和领域建模的各个方面。显然,每个域都会认为某些类似Empty的值是不可接受的,比如空字符串、空数组、0、Guid.Empty等。
如果基础值类型的状态对我的类所表示的概念无效,那么我可以添加Empty、Undefined或类似的无效基础值来表示此状态。但除此之外,我想不出添加Empty属性而不是仅使用null的理由。
当需要表示底层类型的未定义值时,可以使用可为null的类型。
Boolean
变量只能有两个值:true和false。没有"未定义"的值。在许多编程应用程序中,尤其是数据库交互中,变量值可能未定义或丢失。例如,数据库中的字段可能包含true或false值,也可能根本不包含值。在这种情况下,您使用Nullable<bool>
类型。
当您的应用程序与第三方数据库/服务通信时,可以为null的类型可能最有用,因为您的控制非常有限或完全没有控制权。
让我们假设,您的一个应用程序处理不同的源。您必须将源值分配给一个具有Reference Types (string, class, list etc.)
和Value Types (int, double, bool etc)
属性的类。
您无法控制在应用程序中接收的值。虽然Reference Types
将优雅地处理任何null值,但Value Types
将抛出运行时异常。这就是Nullable类型为您节省时间的地方。一旦将值分配给类属性,您就可以自由地按照自己想要的方式处理它们。
您可以在此处获取有关此主题的更多信息:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/nullable-types/
希望这能有所帮助!
为什么有些程序员使用Empty
(或Unknown
或Undefined
)实例而不是使用null
来编写类,正确的答案是这是一种编程技术。
优点:它提供了一个可以访问成员的实例。您的大部分代码不再需要进行null检查,因为永远不会传递null值;相反,这个实例被传递。
从技术上讲:Empty
不应该是指Unknown/Undefined
。例如,当不关心是否在某个地方显式设置了变量时,String.Empty
是一个有用的值。如果您希望代码正常工作,请使用它。
如果您关心检测";从不初始化";,则将其保留为null
,或者创建一个Unknown
(或Undefined
)实例。这在实现上与Empty
相同,只是使用不同而已。按照惯例。
名字很重要。
我个人不使用这种技术。与检查这个特殊实例(当我需要知道它是否为未知时)相比,我发现在任何值可能为null的地方执行null检查都不那么令人困惑。
或者换一种说法:我不喜欢这种技术倾向于";把问题传下去";到其他代码。对我来说,尽早发现错误比让编程更方便更重要。当程序员编写代码时,他们应该";知道";(定义/决定/声明);空";在给定的点是否允许。如果一个";空";被错误地传递到不允许的地方,我希望立即出现异常。
一些较新的语言强化了这种知识;可以为null";以及";不可为null";变量,甚至是类实例。这是我的偏好:;声明";在前面。理想情况下;空";如果允许,则需要程序员说明如何处理null。F#这样做,IIRC。或者也许这只是他们的";图案";("开关/情况"的概括);完整规范";。
如果类程序员使用这种技术,他们必须确保在任何试图更改这个特殊的Empty实例时抛出异常。
在大多数语言中,确保这一点非常麻烦:任何可写属性都必须包含逻辑,以检查是否是正在修改的Empty实例。如果是,则抛出异常。
(字符串类没有这个问题,因为所有实例都是不可变的:任何创建更改字符串的操作,都会将其作为新的字符串实例返回,使原始字符串保持不变。)
理想情况下,一种语言有一个";真"只读";能力,可以保证一个对象是";不可变";。(与C#和其他C风格语言相比,后者允许"只读"变量的属性仍然是可写的。当你想要它时,这很有用;缺少的是一种声明实例是完全不可变的,但其他实例可能会发生变化的方法。)
-
e。g.
string.Empty
使操作成为可能,而null
会失败,抛出NullReferenceException
。 -
如果在代码中处处使用
""
而不是string.Empty
,则会为每次使用创建一个新的string
实例,从而浪费内存。
NB:至少对于string
,Empty
属性不是Singleton
,而是静态属性。