Чому це не складається?
int? number = true ? 5 : null;
Тип умовного вираження неможливо визначити, оскільки немає неявного перетворення між 'int' та <null>
Чому це не складається?
int? number = true ? 5 : null;
Тип умовного вираження неможливо визначити, оскільки немає неявного перетворення між 'int' та <null>
Відповіді:
Специфікації (§7.14) говорять , що для умовного виразу b ? x : y, є три можливості, або xі yобидва мають типу і певні умови , хороші виконані, тільки один з xі yмають тип , і певні умови , хороші будуть виконані, або під час компіляції помилки трапляється. Тут "певні хороші умови" означають можливі певні перетворення, про які ми детально опишемося нижче.
Тепер перейдемо до германської частини специфікації:
Якщо тільки один з
xіyмає тип, і обидва,xіyнеявно перетворюються на цей тип, то це тип умовного виразу.
Проблема тут полягає в тому, що в
int? number = true ? 5 : null;
лише один із умовних результатів має тип. Ось xце intбуквально, і yце nullяка не НЕ мають типу і nullНЕ неявно розкладається в int1 . Тому "певні хороші умови" не виконуються, і виникає помилка часу компіляції.
Там є два шляхи навколо цього:
int? number = true ? (int?)5 : null;
Тут ми всі ще в тому випадку , коли тільки один з xі yмає тип. Зверніть увагу , що до null сих пір не має типу поки компілятор не матиме жодних проблем з цим , тому що (int?)5і nullобидва неявно перетворені в int?(§6.1.4 і §6.1.5).
Інший спосіб очевидно:
int? number = true ? 5 : (int?)null;
але тепер ми повинні прочитати інший пункт у специфікації, щоб зрозуміти, чому це нормально:
Якщо
xмає типXіyмає тип,Yто
Якщо неявне перетворення (§6.1) існує з
XдоY, але не відYдоX, тоYє тип умовного виразу.Якщо неявне перетворення (§6.1) існує з
YдоX, але не відXдоY, тоXє тип умовного виразу.В іншому випадку не можна визначити тип виразу, і виникає помилка часу компіляції.
Тут xє тип intі yє тип int?. Немає неявної конверсії з int?в int, але є неявна конверсія з intу int?такий тип виразу int?.
1 : Зауважте далі, що тип лівої частини ігнорується при визначенні типу умовного виразу, що тут є загальним джерелом плутанини.
new int?()замість (int?)null.
DateTime, коли він Infact потрібно(DateTime?)
null не має жодного ідентифікуючого типу - для його задоволення просто потрібно трохи підтягнути:
int? number = true ? 5 : (int?)null;
int? number = true ? 5 : null as int?;
int? number = true ? 5 : (int?)null;і int? number = true ? (int?)5 : null;обидва складають !! Скретч, подряпин
Як уже згадували інші, 5 є an int, і nullне може бути неявно перетворений в int.
Ось інші способи вирішити проблему:
int? num = true ? 5 : default(int?);
int? num = true ? 5 : new int?();
int? num = true ? 5 : null as int?;
int? num = true ? 5 : (int?)null;
int? num = true ? (int?)5 : null;
int? num = true ? 5 as int? : null;
int? num = true ? new int?(5) : null;
Крім того, де б ви не бачились int?, ви також можете використовувати Nullable<int>.
У C# 9цьому зараз дозволений блог
Ціль набрана ?? і?
Іноді умовні ?? і?: вирази не мають очевидного спільного типу між гілками. Сьогодні такі випадки не вдається, але C # 9.0 дозволить їм, якщо є цільовий тип, який обидві гілки перетворюють на:
Person person = student ?? customer; // Shared base type
int? result = b ? 0 : null; // nullable value type
Або ваш приклад:
// Allowed in C# 9.
int? number = true ? 5 : null;