在 C# 中使用条件运算符输入结果

发布于 2024-09-01 12:49:10 字数 1307 浏览 10 评论 0原文

我正在尝试使用条件运算符,但我对它认为结果应该是什么类型感到困惑。

下面是我设计的一个示例来显示我遇到的问题:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦里°也失望 2024-09-08 12:49:10

编译器不会根据结果的使用来推断条件运算符结果的类型,而是根据其参数的类型来推断。当编译器看到此表达式时会失败,因为它无法推断出结果的类型:

IsDateTimeHappy(myDateTime) ? null : myDateTime;

由于 nullDateTime 不兼容,因此您需要告诉编译器该类型应该是什么是。强制转换应该可以解决问题:

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

现在编译器将不再有问题。如果您愿意,您也可以将以上内容写在一行上(但我可能不会这样做):

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

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:

IsDateTimeHappy(myDateTime) ? null : myDateTime;

Since null and DateTime are not compatible, you need to tell the compiler what the type should be. A cast should do the trick:

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

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):

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

Eric Lippert has a good answer that is also relevant here and goes into more details about how the compiler determines types.

野鹿林 2024-09-08 12:49:10

原因是三元运算符期望两个操作数具有相同的类型。整个运算符在分配给结果(在本例中传递给函数)之前就已经计算出来,因此编译器无法知道结果类型是什么。

IsDateTimeHappy(myDateTime) ? null : myDateTime

在上述情况下,nullDateTime 之间没有转换路径。一旦将其中一个转换为 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?,因为后者是引用类型。

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.

IsDateTimeHappy(myDateTime) ? null : myDateTime

In the above case there is no conversion path between null and DateTime. As soon as you cast one of them to DateTime?, the compiler can convert the other one:

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

The fist line of code above works because the compiler can convert DateTime to DateTime? via an implicit conversion operator:

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

The second line works because null can be assigned to DateTime? since the latter is a reference type.

Smile简单爱 2024-09-08 12:49:10

return 语句不允许隐式转换。如果你有

if (condition)
    return first_expression;
else
    return second_expression;

那么你就会进行同类比较。正如你所说,你不会有任何问题。

在您的情况下,您在堆栈上为 DateTime 分配了如此多的空间 - 这是一个不可为空的值类型。所以你所做的声明对编译器来说没有任何意义。如果您说,我将向您传递一个 AB,然后是 AB > 需要是同一件事。就您而言,B 永远不可能是A

The implicit conversion is not allowed by the return statement. If you had

if (condition)
    return first_expression;
else
    return second_expression;

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 a B, then the A and the B need to be the same thing. In your case, the B can never be an A.

|煩躁 2024-09-08 12:49:10

编译器所说的是:

如果IsDateTimeHappy(myDateTime)false,那么我需要返回一个DateTime类型的值,等于myDateTime代码>.如果是true,那么我需要返回一个等于null的值,但是你还没有告诉我它应该是什么类型!

这就是为什么马克的答案就是解决方案。在您提供强制转换告诉编译器如果条件为 true 时将返回什么类型的值后,编译器可以检查是否为 true 和 false返回值可以转换为(或属于)相同类型。

干杯马克! ;-)

What the compiler is saying is:

If IsDateTimeHappy(myDateTime) is false, then I need to return a value of type DateTime equal to myDateTime. If it is true, then I need to return a value equal to null, but you haven't told me what type it should be!

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 the true and false return values can be converted to (or are of) the same type.

Cheers Mark! ;-)

抚笙 2024-09-08 12:49:10

使用 default(DateTime?) 而不是 null,然后三元组的两边都将具有兼容的类型。

Instead of null use default(DateTime?) and then both sides of the ternary will have compatible types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文