Защо не мога да използвам троичен оператор с този израз?

var dict = new Dictionary<string, object>();
DateTime? myDate;

/*Next line gives: Type of conditional expression cannot be 
determined because there is no implicit conversion between 'System.DateTime?' 
and 'System.DBNull' */

dict.Add("breakit", myDate.HasValue ? myDate.Value : DBNull.Value);

Не разбирам защо трябва да има имплицитно преобразуване, ако едното или другото влиза в речник, очакващ тип Object.


person scottm    schedule 28.06.2011    source източник
comment
Това е изключително често задаван въпрос на SO. Вижте stackoverflow.com/questions/2215745/ за подробности. Вижте също моята свързана статия blogs.msdn.com/b/ericlippert/archive/2010/05/27/   -  person Eric Lippert    schedule 28.06.2011
comment
@Ерик, ще го проверя. Благодаря!   -  person scottm    schedule 28.06.2011
comment
Моля. Проблемът е, че разсъждавате в обратната посока на това, което разсъждава компилаторът. Казваш, че знам, че това ще бъде нещо, което очаква обект. Но компилаторът не знае, че вие ​​a priori желаете методът на обекта да бъде избран. Компилаторът се опитва да разсъждава по друг начин. Пита се методът, който очаква обект, съвместим ли е с този израз? За да знаете, че трябва да попитате Какъв е типът на израза? Проблемът е, че не може да определи типа на израза, за да реши дали изразът работи.   -  person Eric Lippert    schedule 28.06.2011


Отговори (2)


В C# всеки условен израз трябва да има тип. Какъв тип е вашето изражение?

Разбирам загрижеността ви, преобразуването не е необходимо за вашия конкретен случай, но така работи C# компилаторът, така че трябва да спазвате правилата му.

Вместо това трябва да работи (все пак не проверих):

dict.Add("breakit", myDate.HasValue ? (object)myDate.Value : (object)DBNull.Value);
person Zruty    schedule 28.06.2011
comment
моят израз трябва да бъде от тип System.DateTime или DBNull в зависимост от условието на myDate.Value - person scottm; 28.06.2011
comment
тогава това не е статичен тип, а динамичен тип. Компилаторът на C# е със статичен тип (с изключение на някои dynamic механики, за които не съм напълно сигурен). - person Zruty; 28.06.2011
comment
Всъщност не е вярно, че всеки израз трябва да има тип, но е вярно, че всеки условен израз трябва да има тип. Има четири израза в C#, които нямат тип. Нулевият литерал, ламбда, анонимен метод и група методи. Във всеки случай информацията за типа протича от контекста към израза, а не от израза навън, както обикновено. - person Eric Lippert; 28.06.2011
comment
Благодаря за уточнението, +1 - person Zruty; 28.06.2011

Опита ли:

DateTime? date = myDate.HasValue ? myDate.Value : null;

dict.Add("breakit", date);
person Ken D    schedule 28.06.2011
comment
Въпреки това, не разбирам защо трябва да прехвърляме към обект, когато това е главният базов клас! - person Ken D; 28.06.2011