在 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 ---------------+
在上面指出的行上,我收到以下编译错误:
无法确定条件表达式的类型,因为 '<; 之间没有隐式转换。空>'和 'System.DateTime'
我很困惑,因为参数是可为空的类型(DateTime?)。为什么它需要转换?如果它为空,则使用它,如果它是日期时间,则使用它。
我的印象是:
condition ? first_expression : second_expression;
与:
if (condition)
first_expression;
else
second_expression;
显然事实并非如此。这背后的原因是什么?
(注意:我知道如果我将“myDateTime”设置为可为空的日期时间,那么它就会起作用。但是为什么它需要它?
正如我之前所说,这是一个人为的示例。在我的真实示例中,“myDateTime”是一个数据映射值,不能为空。)
I am trying to use the conditional operator, but I am getting hung up on the type it thinks the result should be.
Below is an example that I have contrived to show the issue I am having:
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 ---------------+
On the line indicated above, I get the following compile error:
Type of conditional expression cannot be determined because there is no implicit conversion between '< null >' and 'System.DateTime'
I am confused because the parameter is a nullable type (DateTime?). Why does it need to convert at all? If it is null then use that, if it is a date time then use that.
I was under the impression that:
condition ? first_expression : second_expression;
was the same as:
if (condition)
first_expression;
else
second_expression;
Clearly this is not the case. What is the reasoning behind this?
(NOTE: I know that if I make "myDateTime" a nullable DateTime then it will work. But why does it need it?
As I stated earlier this is a contrived example. In my real example "myDateTime" is a data mapped value that cannot be made nullable.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
编译器不会根据结果的使用来推断条件运算符结果的类型,而是根据其参数的类型来推断。当编译器看到此表达式时会失败,因为它无法推断出结果的类型:
由于
null
和DateTime
不兼容,因此您需要告诉编译器该类型应该是什么是。强制转换应该可以解决问题:现在编译器将不再有问题。如果您愿意,您也可以将以上内容写在一行上(但我可能不会这样做):
Eric Lippert 有一个 好答案,这也与这里相关,并详细介绍了编译器如何确定类型。
The compiler does not infer the type of the result of the conditional operator from the usage of the result, but from the types of its arguments. The compiler fails when it sees this expression because it cannot deduce the type of the result:
Since
null
andDateTime
are not compatible, you need to tell the compiler what the type should be. A cast should do the trick:Now the compiler will have no problems. You can also write the above on one line if you prefer (but I would probably not do this):
Eric Lippert has a good answer that is also relevant here and goes into more details about how the compiler determines types.
原因是三元运算符期望两个操作数具有相同的类型。整个运算符在分配给结果(在本例中传递给函数)之前就已经计算出来,因此编译器无法知道结果类型是什么。
在上述情况下,
null
和DateTime
之间没有转换路径。一旦将其中一个转换为DateTime?
,编译器就可以转换另一个:上面的第一行代码有效,因为编译器可以将
DateTime
转换为DateTime?
通过隐式转换运算符:第二行有效,因为
null
可以分配给DateTime?
,因为后者是引用类型。The reason is the ternary operator expects both the operands to be of the same type. The whole operator get worked out BEFORE it is assigned to a result (in this case passed into a function), so the compiler can't know what the result type is.
In the above case there is no conversion path between
null
andDateTime
. As soon as you cast one of them toDateTime?
, the compiler can convert the other one:The fist line of code above works because the compiler can convert
DateTime
toDateTime?
via an implicit conversion operator:The second line works because
null
can be assigned toDateTime?
since the latter is a reference type.return 语句不允许隐式转换。如果你有
那么你就会进行同类比较。正如你所说,你不会有任何问题。
在您的情况下,您在堆栈上为 DateTime 分配了如此多的空间 - 这是一个不可为空的值类型。所以你所做的声明对编译器来说没有任何意义。如果您说,我将向您传递一个
A
或B
,然后是A
和B
> 需要是同一件事。就您而言,B
永远不可能是A
。The implicit conversion is not allowed by the return statement. If you had
Then you'd be comparing apples to apples. And you'd have no problems - as you stated.
In your case, you're allocated so much space on the stack for a DateTime - which is a non-nullable value type. So you're making a statement that doesn't make any sense to the compiler. If you say, I'm going to pass you an
A
or aB
, then theA
and theB
need to be the same thing. In your case, theB
can never be anA
.编译器所说的是:
这就是为什么马克的答案就是解决方案。在您提供强制转换告诉编译器如果条件为 true 时将返回什么类型的值后,编译器可以检查是否为 true 和 false返回值可以转换为(或属于)相同类型。
干杯马克! ;-)
What the compiler is saying is:
That's why Mark's answer is the solution. After you provide a cast telling the compiler what type of value will be returned if the condition is
true
, it can check whether thetrue
andfalse
return values can be converted to (or are of) the same type.Cheers Mark! ;-)
使用
default(DateTime?)
而不是null
,然后三元组的两边都将具有兼容的类型。Instead of
null
usedefault(DateTime?)
and then both sides of the ternary will have compatible types.