开发者

Why use (int?) null when adopt object initializer?

开发者 https://www.devze.com 2023-03-17 05:23 出处:网络
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class User
    {
        public int? Age { get; set; }
        public int? ID { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            user.Age = null;        // no warning or error
            user.ID  = (int?)null;  // no warning or error

            stri开发者_开发百科ng result = string.Empty;
            User user2 = new User
                             {
                Age = string.IsNullOrEmpty(result) ? null : Int32.Parse(result),
                // Error    1   Type of conditional expression cannot be determined 
                // because there is no implicit conversion between '<null>' and 'int'   
                // ConsoleApplication1\ConsoleApplication1\Program.cs   23  71  ConsoleApplication1

                ID = string.IsNullOrEmpty(result) ? (int?)null : Int32.Parse(result) // // no warning or error
                             };
        }
    }
}

Question:

Why the following line doesn't work?

Age = string.IsNullOrEmpty(result) ? null : Int32.Parse(result)

// Correction one is

Age = string.IsNullOrEmpty(result) ? (int?) null : Int32.Parse(result)

Why the following line work?

user.Age = null;        // no warning or error


Its because the ternary operator needs the return types to be the same type.

In the 1st case "null" could be a null of any reference type (not just int?) so to make it explicit to the compiler it needs casting.

Otherwise you could have

string x = null;
Age = string.IsNullOrEmpty(result) ? x: Int32.Parse(result)

which is obviously a bit cuckooo.


Age = string.IsNullOrEmpty(result) ? null : Int32.Parse(result)

Doesn't work because the string.IsNullOrEmpty(result) ? null : Int32.Parse(result) is evaluated separately from the Age = part.

The compiler can't figure out what type string.IsNullOrEmpty(result) ? null : Int32.Parse(result) is supposed to be.

It first sees null which indicates that it's a reference type, and it sees an int which is a value type which seems incompatible. The fact that there exists a type with an implicit cast operator from int to int? isn't inferred by the compiler.

It could in theory have enough information to figure it out but the compiler would need to be a lot more sophisticated.


Because C# enforces that every expression must have a type. The compiler is unable to determine the type of the ternary expression in the non-working line.


The ? : inline if operator does not know which type to return because the two arguments are null and int. Since int cannot ever be null, the compiler cannot resolve the type returned by ?:.

0

精彩评论

暂无评论...
验证码 换一张
取 消