Why does .ToString() on a null string cause a null error, when .ToString() works fine on a nullable int with null value?

前端 未结 8 1091
耶瑟儿~
耶瑟儿~ 2020-11-30 12:19

selectedItem has two fields:

  • int? _cost
  • string _serialNumber

In this example, _cost

相关标签:
8条回答
  • 2020-11-30 12:33

    int? is not actually an object in its own but it's a Nullable<int> object.

    So when you declare int? _Cost, you are actually declaring Nullable<int> _Cost and the property of _Cost.Value is undefined not the _Cost object itself.

    It is actually a syntactic sugar to use non nullable types like int, bool or decimal easily.

    According to MSDN:

    The syntax T? is shorthand for System.Nullable<T>, where T is a value type. The two forms are interchangeable.

    0 讨论(0)
  • 2020-11-30 12:42

    The Nullable is actually a struct exposing two properties: HasValue and Value. If you do this you will get your error:

    int? i = null;
    i.Value.ToString()
    

    In order to check whether or not your int? has a value you can access i.HasValue

    0 讨论(0)
  • 2020-11-30 12:47

    A Nullable<int> is a struct and can't really be null. So a method call on a "null" struct still works.

    There is some "compiler magic" that makes _cost == null a valid expression.

    0 讨论(0)
  • 2020-11-30 12:49

    what i think the reason is, when the compiler encounters a primitive data type it wraps it, to its corresponding object. The toString() method call is just an indirect call(wrapping and then calling the method) here and the exception is handled there. While in the case of String, we are directly calling the method. When pointing to a null, the method throws the exception.

    0 讨论(0)
  • 2020-11-30 12:57

    The reason is simple. int? or Nullable<int> is a struct or a value type, it can never be null.

    So what happens when we do:

    int? _cost = null;
    

    _cost will have two fields Value and HasValue, when we assign null to _cost its HasValue flag will be set to false and the Value field would be assigned default(T) in case of int? it would 0.

    Now when we call ToString on _cost, Nullable<T> has an override definition of ToString, which if we look at Microsoft's provided Source Reference is implemented like:

    public override string ToString() {
        return HasValue ? value.ToString() : "";
    }
    

    Thus it returns an empty string, since _cost is assigned null.

    Now comes the case of string _serialNumber. Being string it is a reference type and it can purely hold null. If it is holding null then calling ToString on it would produce the Null Reference Exception as expected.

    You may see: Value Types and Reference Types - MSDN

    0 讨论(0)
  • 2020-11-30 12:58

    Because string type's null really points to nothing, there isn't any object in memory.
    But int? type(nullable) even with value set to null still points to some object.
    If you read Jeffrey Richter's "CLR via C#" you'll find out that nullable type are just facade classes for common types with some incapsulated logics in order to make work with DB null more convenient.

    Check msdn to learn about nullable types.

    0 讨论(0)
提交回复
热议问题