Вопрос

Я пытаюсь использовать условный оператор, но я вижу на том типе, который думает, что результат должен быть.

Ниже приведен пример, который я придумал показать проблему, у меня есть:

class Program
{
    public static void OutputDateTime(DateTime? datetime)
    {
        Console.WriteLine(datetime);
    }

    public static bool IsDateTimeHappy(DateTime datetime)
    {
        if (DateTime.Compare(datetime, DateTime.Parse("1/1")) == 0)
            return true;

        return false;
    }

    static void Main(string[] args)
    {
        DateTime myDateTime = DateTime.Now;
        OutputDateTime(IsDateTimeHappy(myDateTime) ? null : myDateTime);
        Console.ReadLine();                        ^
    }                                              |
}                                                  |
// This line has the compile issue  ---------------+

В строке указана выше, я получаю следующую ошибку компиляции:

Тип условного выражения не может быть определен, потому что нет неявного преобразования между «<NULL>» и «System.DateTime»

Я запутался, потому что параметр - ненужный тип (DateTime?). Почему нужно вообще конвертировать? Если это значение NULL, тогда используйте это, если это дата времени, а затем используйте это.

Я был под впечатлением, что:

condition ? first_expression : second_expression;

был таким же, как:

if (condition)
   first_expression;
else
   second_expression;

Ясно, что это не так. Что такое рассуждение за этим?

(Примечание: я знаю, что если я сделаю «MyDateTime» Nulleble DateTime, то он будет работать. Но почему это нужно?

Как я заявил ранее, это надуманный пример. В моем реальном примере «MyDateTime» - это отображенное значение, которое не может быть сделано ненужным.)

Это было полезно?

Решение

Компилятор не делает вывод типа результата условного оператора от использования результата, но из типов его аргументов. Компилятор терпит неудачу, когда он видит это выражение, потому что он не может вывести тип результата:

IsDateTimeHappy(myDateTime) ? null : myDateTime;

С null а также DateTime Не совместимы, вам нужно сказать компилятору, какой тип должен быть. Слома должна сделать трюк:

DateTime? x = IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime;
OutputDateTime(x);

Теперь компилятор не будет проблем. Вы также можете написать выше на одну строку, если вы предпочитаете (но я бы, вероятно, не сделаю это):

OutputDateTime(IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime);

Эрик ЛПППЕРТ имеет хороший ответ Это также актуально здесь и входит в более подробную информацию о том, как компилятор определяет типы.

Другие советы

Причина в том, что Тернарный оператор ожидает как операнды, чтобы иметь одинаковый тип. Весь оператор разрабатывается до того, как он будет назначен результатом (в этом случае передается в функцию), поэтому компилятор не может знать, что такое тип результата.

IsDateTimeHappy(myDateTime) ? null : myDateTime

В приведенном выше случае нет пути преобразования между null а также DateTime. Отказ Как только вы бросаете один из них DateTime?, Компилятор может преобразовать другой:

IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime
//OR
IsDateTimeHappy(myDateTime) ? null : (DateTime?)myDateTime

Кулачная линия кода выше работает, потому что компилятор может преобразовать DateTime к DateTime? через неявный оператор преобразования:

//In Nullable<T>
public static implicit operator T?(T value);

Вторая строка работает, потому что null можно назначить DateTime? Поскольку последний является ссылочным типом.

Неявное преобразование не допускается оператором возврата. Если у тебя есть

if (condition)
    return first_expression;
else
    return second_expression;

Тогда вы бы сравнивали яблоки к яблокам. И у вас не было бы проблем - как вы заявили.

В вашем случае вы выделяете так много места на стеке для DateTime - который является ненужным типом значения. Таким образом, вы делаете заявление, которое не имеет смысла для компилятора. Если вы говорите, я собираюсь передать вам A или а B, тогда то A и то B нужно быть то же самое. В вашем случае B никогда не может быть A.

Я думаю, что это также отвечает здесь:Знаменимые типы и тройной оператор: почему? 10: null` запрещено?

Надеюсь, что это то, что вам нужно. знак равно

Что говорит компилятор:

Если IsDateTimeHappy(myDateTime) является false, тогда мне нужно вернуть значение типа DateTime равно myDateTime. Отказ Если это true, тогда мне нужно вернуть ценность, равное null, но вы не сказали мне, какой тип должен быть!

Вот почему ответ Марка - это решение. После того, как вы предоставляете отказ от компилятора Какой тип стоимости будет возвращен, если условие true, это может проверить, true а также false Возвращает значения могут быть преобразованы в (или имеют) тот же тип.

Ура Марк! ;-)

Вместо null использовать default(DateTime?) А потом обе стороны тройника будут иметь совместимые типы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top