为什么 Convert.ToInt32(null) 在 c# 中返回 0

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11580208/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 18:26:22  来源:igfitidea点击:

Why Convert.ToInt32(null) returns 0 in c#

c#null

提问by GigaPr

I just came across this today, if you convert null to int32

我今天刚遇到这个,如果你把 null 转换成 int32

Convert.ToInt32(null)

it returns 0

它返回 0

I was expecting an InvalidCastException...

我期待一个 InvalidCastException ......

Any idea why this happen?

知道为什么会这样吗?

回答by JMK

Because the default value of an Int32 is zero. Int32's cannot be null as they are value types, not reference types, so you get the default value instead.

因为 Int32 的默认值为零。Int32 不能为空,因为它们是值类型,而不是引用类型,因此您将获得默认值。

回答by Tim S.

Because that's what is documentedthat it will return. Perhaps you were thinking of (int)null, which would be an NullReferenceException(not InvalidCastException; I'm not sure why).

因为那是什么文件,它会返回。也许你在想(int)null,这将是一个NullReferenceException(不是InvalidCastException;我不知道为什么)。

回答by Jon Skeet

Any idea why this happen?

知道为什么会这样吗?

Because that's the documented behaviour? Whether it's Convert.ToInt32(object)or Convert.ToInt32(string), the documentation states quite clearly:

因为这是记录在案的行为?无论是Convert.ToInt32(object)还是Convert.ToInt32(string),文档都非常清楚地说明:

(Under return value)

(在返回值下)

A 32-bit signed integer that is equivalent to the number in value, or 0 (zero) if value is null.

一个 32 位有符号整数,等效于 value 中的数字,如果 value 为 null,则为 0(零)。

or

或者

A 32-bit signed integer equivalent to value, or zero if value is null.

与 value 等效的 32 位有符号整数,如果 value 为 null,则为零。

As always, if reality doesn't match expectations, the first thing you should do is check whether your expectations match the documented behaviour.

与往常一样,如果现实与期望不符,您应该做的第一件事是检查您的期望是否与记录的行为相符。

Personally I don't fully buy the "compatibility with VB6" argument shown by Gavin. I realize it comes from Microsoft, and it may well be the genuine reason why it behaves that way - but I don't think it's a goodreason to behave that way. There are plenty of VB-specific conversion methods - so if the framework designers genuinely thought that returning zero was a non-ideal result, they should have done whatever they thought best, and provided a VB6 compatible conversion for use by VB6 programmers.

就我个人而言,我并不完全认同 Gavin 所展示的“与 VB6 的兼容性”的说法。我意识到它来自微软,这很可能是它这样做的真正原因——但我认为这不是这样做的理由。有很多特定于 VB 的转换方法——所以如果框架设计者真的认为返回零是一个不理想的结果,他们应该做他们认为最好的事情,并提供一个 VB6 兼容转换供 VB6 程序员使用。

Obviously once the behavior was defined in .NET 1.0, it couldn't be changed for later versions - but that's not the same as saying it had to behave the same way as VB6.

显然,一旦在 .NET 1.0 中定义了该行为,就无法在以后的版本中对其进行更改 - 但这与说它的行为方式必须与 VB6 相同是不同的。

回答by Gavin

See http://msdn.microsoft.com/en-us/library/sf1aw27b.aspx

请参阅http://msdn.microsoft.com/en-us/library/sf1aw27b.aspx

Edit

编辑

The URL above automatically reverts to the latest Framework version, where as the text below was specifically posted on version 4. See the revised URL below which shows the text.

上面的 URL 会自动恢复到最新的 Framework 版本,因为下面的文本专门发布在第 4 版上。请参阅下面显示文本的修订后的 URL。

http://msdn.microsoft.com/en-us/library/sf1aw27b(v=vs.100).aspx

http://msdn.microsoft.com/en-us/library/sf1aw27b(v=vs.100).aspx

It explains:

它解释说:

All of the string-to-numeric conversion methods in the Convert class return zero if the string is null. The original motivation for this behavior was that they would provide a set of conversion methods for programmers migrating from Visual Basic 6 to Visual Basic .NET that mirrored the behavior of the existing Visual Basic 6 conversion methods. The assumption was that C# programmers would be more comfortable with casting operators, whereas Visual Basic had traditionally used conversion methods for type conversion.

Traditionally, the .NET Framework has tried to maintain a high degree of compatibility from version to version. Effectively, this means that, absent an extremely compelling reason, once a method has been implemented in a particular way and that implementation is publicly exposed (as in a method returning 0 if the string parameter is null), it cannot be changed, since that would break code that depends on the established behavior. This makes both of your proposed solutions very problemmatic. In the first case, throwing an exception changes the implementation of a method for customers who are likely to depend on the method returning zero for a null string. In the second case, it is important to remember that the .NET Framework does not consider return type in overload resolution. This means that your method would have to replace the existing Convert.ToInt32(String value) method, and that all code that does not expect to handle a nullable type would now be broken.

This concern for compatibility is even stronger in the case of the string-to-numeric conversion methods in the Convert class, since Parse is the recommended method for performing string-to-numeric conversion for each of the primitive numeric types supported by the .NET Framework, and each Parse method behaves differently that its corresponding Convert method. Unlike the string-to-numeric conversion method in the Convert class, which return zero if the string to be converted is null, each Parse method throws an ArgumentNullException, which is the behavior that you are arguing for. The overloads of the numeric Parse methods, such as Int32.Parse and Double.Parse, also have the advantage of allowing much finer-grained control over the parsing operation.

如果字符串为空,则 Convert 类中的所有字符串到数字转换方法都返回零。这种行为的最初动机是,它们将为从 Visual Basic 6 迁移到 Visual Basic .NET 的程序员提供一组转换方法,这些方法反映了现有 Visual Basic 6 转换方法的行为。假设是 C# 程序员更喜欢使用强制转换运算符,而 Visual Basic 传统上使用转换方法进行类型转换。

传统上,.NET Framework 一直试图保持版本与版本之间的高度兼容性。实际上,这意味着,如果没有非常令人信服的理由,一旦以特定方式实现了一个方法并且该实现被公开公开(如在字符串参数为 null 时返回 0 的方法中),它就无法更改,因为会破坏依赖于既定行为的代码。这使您提出的两个解决方案都非常有问题。在第一种情况下,对于可能依赖为空字符串返回零的方法的客户,抛出异常会更改方法的实现。在第二种情况下,重要的是要记住 .NET Framework 在重载解析中不考虑返回类型。这意味着您的方法必须替换现有的 Convert。

在 Convert 类中的字符串到数字转换方法的情况下,这种对兼容性的关注更加强烈,因为 Parse 是为 .NET 支持的每个基本数字类型执行字符串到数字转换的推荐方法框架,每个 Parse 方法的行为与其对应的 Convert 方法不同。与 Convert 类中的字符串到数字转换方法不同,如果要转换的字符串为空,则返回零,每个 Parse 方法都会抛出一个 ArgumentNullException,这是您要争论的行为。数值 Parse 方法的重载,例如 Int32.Parse 和 Double.Parse,还具有允许对解析操作进行更细粒度控制的优点。

回答by Shyju

Because this is how the method is written in the Convert class . If the parameter value is nullit is simply returning 0.

因为这是在 Convert 类中编写方法的方式。如果参数值是null它只是返回 0。

public static int ToInt32(object value)
{
    if (value == null)
    {
        return 0;
    }
    else
    {
        return ((IConvertible)value).ToInt32(null);
    }
}

回答by Daniel Ferreira

For you to have an InvalidCastException you have to make a non-controlledcast.

要获得 InvalidCastException,您必须进行非受控转换

For example:

例如:

int i = (int)null;

If you execute it the exception should be raised.

如果您执行它,则应该引发异常。

The use of

指某东西的用途

Convert.ToInt32(var)

Is useful when you distrust the value in var, as when reading from a database.

当您不信任var 中的值时很有用,例如从数据库中读取时。