以接口为基类的三元表达式 [英] Ternary Expression with Interfaces as a Base Class

查看:25
本文介绍了以接口为基类的三元表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个三元表达式,但出现以下错误

I am attempting to create a ternary expression and I am getting the following error

无法确定条件表达式的类型,因为 LiveSubscription 和 DisconnectedSubscription 之间没有隐式转换"

"Type of conditional expression cannot be determined because there is no implicit conversion between LiveSubscription and DisconnectedSubscription"

同样的逻辑适用于 if 语句,但我想了解为什么它不适用于三元表达式 -

The same logic works in an if statement, but I wanted to understand why it won't work in a ternary expression -

这是我想要做的事情的要点:

Here is the gist of what I am trying to do:

public interface IClientSubscription
{
    bool TryDisconnect();
}

public class LiveSubscription : IClientSubscription
{
    public bool TryDisconnect()
    {
        return true;
    }
}

public class DisconnectedSubscription : IClientSubscription
{
    public bool TryDisconnect()
    {
        return true;
    }
}

public class ConnectionManager
{
    public readonly IClientSubscription Subscription;

    public ConnectionManager(bool IsLive)
    {
        // This throws the exception
        Subscription = (IsLive)
            ? new LiveSubscription()
            : new DisconnectedSubscription();

        // This works
        if (IsLive)
        {
            Subscription = new LiveSubscription();
        }
        else
        {
            Subscription = new DisconnectedSubscription();
        }
    }
}

我总是可以将其切换为 if/else,但我想先了解出了什么问题!

I could always switch it to an if/else but I wanted to understand what is going wrong first!

推荐答案

您需要将至少一个操作数强制转换为 IClientSubscription:

You need to cast at least one of the operands to IClientSubscription:

Subscription = (IsLive)
            ? (IClientSubscription)new LiveSubscription()
            : new DisconnectedSubscription();

原因是三元表达式是由操作数决定的某种类型.基本上,它尝试将第二个操作数强制转换为第一个操作数的类型,反之亦然.两者都失败了,因为 LiveSubscription 不是 DisconnectedSubscription,反之亦然.
编译器不会检查两者是否共享一个共同的基类型.

The reason is that the ternary expression is of a certain type which is determined by the operands. Basically, it tries to cast the second operand to the type of the first or vice versa. Both fail here, because LiveSubscription isn't an DisconnectedSubscription and vice versa.
The compiler doesn't check whether both share a common base type.

尝试在评论中回答您的问题:

Trying to answer your question in the comment:

不,三元表达式不是某种对象,但三元表达式是赋值的右侧部分.赋值的每个右手部分表达式都有特定的类型,否则不可能将此表达式分配给左侧的变量.
示例:

No, ternary expressions are not some sort of object, but a ternary expression is the right hand part of an assignment. Each right hand part expression of an assignment has a certain type, otherwise it would be impossible to assign this expression to the variable on the left hand side.
Examples:

  • var x = Guid.NewGuid()

右侧表达式 (Guid.NewGuid()) 是 Guid 类型,因为方法 NewGuid() 返回一个 <代码>指导.

The right hand side expression (Guid.NewGuid()) is of type Guid, because the method NewGuid() returns a Guid.

var x = y.SomeMethod()

右边的表达式是SomeMethod()的返回类型.

The right hand side expression is of the type of the return type of SomeMethod().

var x = IsLive ?"a" : 1

这显然是无效的,不是吗?x 应该是什么类型?string 还是 int?
这将导致与您的代码完全相同的错误消息.

This is obviously invalid, isn't it? What type should x be? A string or an int?
This would lead to the exact same error message that you had with your code.

你的例子有点变化:

var subscription = (IsLive) ? new LiveSubscription()
                            : new DisconnectedSubscription();

注意 subscription 之前的 var,我们现在初始化一个新变量,而不是现有变量.我认为即使在这里,问题也很明显:subscription 应该是什么类型?LiveSubscription 还是 DisconnectedSubscription?它可以两者都不是,因为取决于 IsLive,它需要是一个或另一个.

Note the var before subscription, we now initialize a new variable, not an existing. I think even here, it is obvious what the problem is: What type should subscription be? LiveSubscription or DisconnectedSubscription? It can be neither, because depending on IsLive it needs to be either the one or the other.

关于与if的比较:

在您将新的 LiveSubscription 实例或新的 DisconnectedSubscription 实例分配给 Subscription 的代码中,隐式转换为 IClientSubscription 正在发生,因为编译器知道 SubscriptionIClientSubscription 类型并且 LiveSubscriptionDisconnectedSubscription 都可以隐式转换为该接口.
三元表达式的赋值有点不同,因为编译器首先尝试对三元表达式求值,然后才尝试将其赋值给 Subscription.这意味着编译器不知道三元表达式的结果需要是 IClientSubscription 类型.

In your code where you assign a new LiveSubscription instance or a new DisconnectedSubscription instance to Subscription an implicit cast to IClientSubscription is occurring, because the compiler knows that Subscription is of type IClientSubscription and both LiveSubscription and DisconnectedSubscription can implicitly be converted to that interface.
The assignment with the ternary expression is a bit different, because the compiler first tries to evaluate the ternary expression and only afterwards it tries to assign it to Subscription. This means that the compiler doesn't know that the result of the ternary expression needs to be of type IClientSubscription.

这篇关于以接口为基类的三元表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆