在 C# 中使用条件运算符输入结果
-
26-09-2019 - |
题
我正在尝试使用条件运算符,但我对它认为结果应该是什么类型感到困惑。
下面是我设计的一个示例来展示我遇到的问题:
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?)。为什么它需要转换?如果它为空,则使用它,如果它是日期时间,则使用它。
我的印象是:
condition ? first_expression : second_expression;
与以下内容相同:
if (condition)
first_expression;
else
second_expression;
显然情况并非如此。这背后的原因是什么?
(笔记:我知道如果我将“myDateTime”设置为可为空的日期时间,那么它就会起作用。但为什么需要它呢?
正如我之前所说,这是一个人为的例子。在我的真实示例中,“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?
因为后者是一个引用类型。
在隐式转换不是由return语句允许的。如果你有
if (condition)
return first_expression;
else
return second_expression;
然后你会比较苹果和苹果。而且你不会有任何问题 - 如你所说
这是一个非空的值类型 -在你的情况,你堆栈的日期时间上分配如此多的空间。所以,你在做一个声明,它没有任何意义的编译器。如果你说,我要通过你的A
或B
,那么A
和B
需要是同一件事。在你的情况下,B
永远是A
。
我想这也是在这里得到解答: 可空类型和三元运算符:为什么`? 10:禁止null`
希望这是你需要的。 =]
什么编译器是说是:
如果
IsDateTimeHappy(myDateTime)
是false
,然后我需要返回类型DateTime
的值等于myDateTime
。如果是true
,然后我需要返回一个值等于null
,但是你还没有告诉我是什么类型是应该的!
这就是为什么马克的回答是解决方案。之后提供流延告诉如果条件为true
什么类型的值将被返回的编译器,它可以检查true
和false
返回值是否可以转换到(或是)相同的类型。
干杯马克! ; - )
代替null
使用default(DateTime?)
然后三元的两侧将具有兼容的类型。