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

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

问题描述

我试图创建一个三元表达式,并得到以下错误

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()返回 Guid

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

var x = y.SomeMethod()

右侧表达式是 SomeMethod()

var x = IsLive? a:1

这显然是无效的,不是吗?什么类型应该 x 是? A 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();

注意之前的 var c> 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.

关于与的比较如果

a LiveSubscription 实例或新的 DisconnectedSubscription 实例订阅因为编译器知道 Subscription 的类型为 IClientSubscription,所以会发生 IClientSubscription ,并且 LiveSubscription DisconnectedSubscription 都可以隐式转换为该接口。

与三元表达式的赋值是有点不同的,因为编译器首先尝试评估三元表达式,然后才尝试将它分配给 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天全站免登陆