为什么我不应该总是在 C# 中使用可空类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/830592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why shouldn't I always use nullable types in C#
提问by Matthew Vines
I've been searching for some good guidance on this since the concept was introduced in .net 2.0.
自从.net 2.0 中引入了这个概念以来,我一直在寻找一些好的指导。
Why would I ever want to use non-nullable data types in c#? (A better question is why wouldn't I choose nullable types by default, and only use non-nullable types when that explicitly makes sense.)
为什么我想在 c# 中使用不可为空的数据类型?(一个更好的问题是为什么我不默认选择可空类型,并且仅在明确有意义的情况下才使用不可空类型。)
Is there a 'significant' performance hit to choosing a nullable data type over its non-nullable peer?
选择可空数据类型而不是不可空数据类型是否会对性能产生“重大”影响?
I much prefer to check my values against null instead of Guid.empty, string.empty, DateTime.MinValue,<= 0, etc, and to work with nullable types in general. And the only reason I don't choose nullable types more often is the itchy feeling in the back of my head that makes me feel like it's more than backwards compatibility that forces that extra '?' character to explicitly allow a null value.
我更喜欢根据 null 而不是 Guid.empty、string.empty、DateTime.MinValue、<= 0 等检查我的值,并且通常使用可空类型。我不经常选择可空类型的唯一原因是我后脑勺发痒的感觉,这让我觉得不仅仅是向后兼容性迫使额外的“?” 字符以明确允许空值。
Is there anybody out there that always (most always) chooses nullable types rather than non-nullable types?
有没有人总是(大多数情况下)选择可空类型而不是不可空类型?
Thanks for your time,
谢谢你的时间,
采纳答案by jalf
The reason why you shouldn't always use nullable types is that sometimes you're able to guarantee that a value willbe initialized. And you should try to design your code so that this is the case as often as possible. If there is no way a value can possibly be uninitialized, then there is no reason why null should be a legal value for it. As a very simple example, consider this:
不应该总是使用可为空类型的原因是有时您能够保证一个值将被初始化。并且您应该尝试设计您的代码,以便尽可能多地出现这种情况。如果一个值不可能被未初始化,那么 null 就没有理由成为它的合法值。作为一个非常简单的例子,考虑一下:
List<int> list = new List<int>()
int c = list.Count;
This is alwaysvalid. There is no possible way in which c
could be uninitialized. If it was turned into an int?
, you would effectively be telling readers of the code "this value might be null. Make sure to check before you use it". But we know that this can never happen, so why not expose this guarantee in the code?
这总是有效的。没有可能c
未初始化的方法。如果它变成了int?
,你实际上是在告诉代码的读者“这个值可能是空的。确保在使用之前检查一下”。但是我们知道这永远不会发生,那么为什么不在代码中公开这个保证呢?
You are absolutely right in cases where a value is optional. If we have a function that may or may not return a string, then return null. Don't return string.Empty(). Don't return "magic values".
在值是可选的情况下,您是绝对正确的。如果我们有一个可能返回也可能不返回字符串的函数,则返回 null。不要返回 string.Empty()。不要返回“魔法值”。
But not all values are optional. And making everything optional makes the rest of your code far more complicated (it adds another code path that has to be handled).
但并非所有值都是可选的。并且将所有内容都设为可选会使您的其余代码变得更加复杂(它添加了另一个必须处理的代码路径)。
If you can specifically guarantee that this value will always be valid, then why throw away this information? That's what you do by making it a nullable type. Now the value may or may not exist, and anyone using the value will have to handle both cases. But you know that only one of these cases is possible in the first place. So do users of your code a favor, and reflect this fact in your code. Any users of your code can then rely on the value being valid, and they only have to handle a single case rather than two.
如果你能特别保证这个值永远有效,那为什么要扔掉这些信息呢?这就是您通过使其成为可空类型来做的事情。现在该值可能存在也可能不存在,任何使用该值的人都必须处理这两种情况。但是您知道,首先这些情况中只有一种是可能的。所以请帮助您的代码的用户,并在您的代码中反映这一事实。您的代码的任何用户都可以依赖该值是有效的,并且他们只需要处理一个案例而不是两个案例。
回答by LukeH
Because it's inconvenient to always have to check whether the nullable type is null
.
因为总是要检查可空类型是否为null
.
Obviously there are situations where a value is genuinely optional, and in those cases it makes sense to use a nullable type rather than magic numbers etc, but where possible I would try to avoid them.
显然,在某些情况下,值是真正可选的,在这些情况下,使用可空类型而不是幻数等是有意义的,但在可能的情况下,我会尽量避免它们。
// nice and simple, this will always work
int a = myInt;
// compiler won't let you do this
int b = myNullableInt;
// compiler allows these, but causes runtime error if myNullableInt is null
int c = (int)myNullableInt;
int d = myNullableInt.Value;
// instead you need to do something like these, cumbersome and less readable
int e = myNullableInt ?? defaultValue;
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere();
回答by Jonathan Rupp
I tend to use Nullable types wherever they make sense -- I won't care about performance until it's a problem, then I'll fix the few areas where it is and be done with it.
我倾向于在任何有意义的地方使用 Nullable 类型——除非出现问题,否则我不会关心性能,然后我会修复它所在的几个区域并完成它。
However, I also find that in general, most of my values end up being non-nullable. In fact, there are many times I'd actually like a NotNullable I can use with reference types to find out about a null problem when I get the null, not later on when I try to use it.
但是,我也发现一般来说,我的大多数值最终都是不可为空的。事实上,很多时候我实际上想要一个 NotNullable 我可以与引用类型一起使用,以便在我获得空值时找出空问题,而不是稍后我尝试使用它时。
回答by Brian
I think the language designers feel that 'reference types being nullable by default' was a mistake, and that non-nullable is the only sensible default, and you should have to opt into nullness. (This is how it is in many modern functional languages.) "null" is usually a heap of trouble.
我认为语言设计者认为“默认情况下引用类型可以为空”是一个错误,不可为空是唯一合理的默认值,您应该选择为空。(这在许多现代函数式语言中都是如此。)“null”通常是一大堆麻烦。
回答by John Rasch
You seem to have 2 different questions...
你似乎有两个不同的问题...
Why would I ever want to use non-nullable data types in C#?
为什么我想在 C# 中使用不可为空的数据类型?
Simple, because the value-type data you're relying on is guaranteed by the compiler to actually have a value!
很简单,因为编译器保证您所依赖的值类型数据实际上具有值!
Why wouldn't I choose nullable types by default, and only use non-nullable types when that explicitly makes sense?
为什么默认情况下我不选择可空类型,而仅在明确有意义的情况下才使用不可空类型?
As Joel has already mentioned, a type can only be null if it is a reference type. Value types are guaranteed by the compiler to have a value. If your program depends on a variable to have a value, then this is the behavior you will want by not choosing a nullable type.
正如 Joel 已经提到的,如果类型是引用类型,它只能为 null。编译器保证值类型具有值。如果您的程序依赖于一个变量来获取值,那么这就是您不选择可为空类型所希望的行为。
Of course, when your data is coming from anywhere that is not your program, then all bets are off. The best example is from a database. Database fields can be null
, so you would want your program variable to mimic this value - not just create a "magic" value (i.e. -1, 0, or whatever) that "represents" null
. You do this with nullable types.
当然,当您的数据来自不是您的程序的任何地方时,所有赌注都将关闭。最好的例子来自数据库。数据库字段可以是null
,因此您希望您的程序变量模仿这个值 - 而不仅仅是创建一个“代表”的“魔术”值(即 -1、0 或其他值)null
。您可以使用可为空类型执行此操作。
回答by Mark Cidade
Although null values can be convenient for using as "not-initialized-yet" or "not-specified" values, they make the code more complex, mainly because you're overloading the meaning of null
as well as the variable (number-or-null vs. just-a-number).
尽管空值可以方便地用作“尚未初始化”或“未指定”的值,但它们使代码更加复杂,主要是因为您重载了 的含义null
以及变量(数字或-空与只是一个数字)。
NULL values are favoured by many database designers and SQL database programmers but with a small change in thinking about the problem you can do away with null values and actually have simpler and more reliable code (e.g., no worrying about NullReferenceException
s).
NULL 值受到许多数据库设计人员和 SQL 数据库程序员的青睐,但只要稍微改变一下对问题的思考,您就可以摆脱 null 值,并且实际上拥有更简单、更可靠的代码(例如,无需担心NullReferenceException
s)。
There's actually a large demand for a "T!" operator that makes any reference type non-nullable, similar to how "T?" makes value types nullable, and Anders Hejlsberg, the inventor of C#, wished he had included the ability.
实际上对“T!”的需求很大。使任何引用类型不可为空的运算符,类似于 "T?" 使值类型可以为空,C# 的发明者 Anders Hejlsberg 希望他能包含这种能力。
See also the question, Why is “null” present in C# and java?
另请参阅问题,为什么 C# 和 java 中存在“null”?
回答by Flagrum
The only time that a Nullable Type should ever be used, is in the case that a certain field in a table of the database absolutely requires that a null be sent or received by the application at some point. Even in such a case, one should always try to find a way around using the Nullable Type. Bool isn't always your best friend.
只有在数据库表中的某个字段绝对需要应用程序在某个时刻发送或接收空值的情况下,才应该使用 Nullable 类型。即使在这种情况下,也应该始终尝试找到一种使用 Nullable 类型的方法。布尔并不总是你最好的朋友。