[英]Type result with conditional operator in C#
我正在尝试使用条件运算符,但我正在挂起它认为结果应该是的类型。
下面是一个我设法表明我遇到的问题的例子:
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”设为可以为空的DateTime,那么它将会起作用。但为什么需要呢?
正如我之前所说,这是一个人为的例子。 在我的实例中,“myDateTime”是一个数据映射值,不能为空。)
编译器不会根据结果的用法推断条件运算符的结果类型,而是根据其参数的类型。 编译器在看到此表达式时失败,因为它无法推断出结果的类型:
IsDateTimeHappy(myDateTime) ? null : myDateTime;
由于null
和DateTime
不兼容,您需要告诉编译器类型应该是什么。 演职员应该做的伎俩:
DateTime? x = IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime;
OutputDateTime(x);
现在编译器没有问题。 如果您愿意,也可以在一行上写上面的内容(但我可能不会这样做):
OutputDateTime(IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime);
Eric Lippert有一个很好的答案 ,这里也很重要,并详细介绍了编译器如何确定类型。
原因是三元运算符期望两个操作数都是相同的类型。 整个运算符在分配给结果之前得到解决(在这种情况下传递给函数),因此编译器无法知道结果类型是什么。
IsDateTimeHappy(myDateTime) ? null : myDateTime
在上面的例子中, null
和DateTime
之间没有转换路径。 一旦你将其中一个投射到DateTime?
,编译器可以转换另一个:
IsDateTimeHappy(myDateTime) ? (DateTime?)null : myDateTime
//OR
IsDateTimeHappy(myDateTime) ? null : (DateTime?)myDateTime
上面的第一行代码是DateTime
,因为编译器可以将DateTime
转换为DateTime?
通过隐式转换运算符:
//In Nullable<T>
public static implicit operator T?(T value);
第二行有效,因为null
可以分配给DateTime?
因为后者是参考类型。
return语句不允许隐式转换。 如果你有
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
,但是你还没有告诉我应该是什么样的!
这就是Mark的答案就是解决方案的原因。 在提供告诉编译器的转换为条件为true
将返回什么类型的值之后,它可以检查true
和false
返回值是否可以转换为(或属于)相同类型。
干杯马克! ;-)
而不是null
使用default(DateTime?)
然后三元的双方都必须兼容的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.