我正在尝试创建一个三元表达式,我收到以下错误
“无法确定条件表达式的类型,因为LiveSubscription和DisconnectedSubscription之间没有隐式转换”
同样的逻辑在if语句中起作用,但我想理解为什么它不能用于三元表达式 -
以下是我要做的事情的要点:
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但是我想先了解出了什么问题!
答案 0 :(得分:9)
您需要将至少一个操作数强制转换为IClientSubscription
:
Subscription = (IsLive)
? (IClientSubscription)new LiveSubscription()
: new DisconnectedSubscription();
原因是三元表达式是由操作数决定的某种类型。基本上,它尝试将第二个操作数转换为第一个操作数,反之亦然。这两个都失败了,因为LiveSubscription
不是DisconnectedSubscription
,反之亦然
编译器不会检查两者是否共享公共基类型。
试着在评论中回答你的问题:
不,三元表达式不是某种对象,但三元表达式是赋值的右手部分。赋值的每个右手部分表达式都有某种类型,否则无法将此表达式赋值给左侧的变量。
例子:
var x = Guid.NewGuid()
右侧表达式(Guid.NewGuid()
)的类型为Guid
,因为方法NewGuid()
会返回Guid
。
var x = y.SomeMethod()
右侧表达式属于SomeMethod()
的返回类型。
var x = IsLive ? "a" : 1
x
应该是什么类型的?一个string
或int
?您的示例有点改变:
var subscription = (IsLive) ? new LiveSubscription()
: new DisconnectedSubscription();
注意var
之前的subscription
,我们现在初始化一个新变量,而不是现有变量。我想即使在这里,问题显然是什么:subscription
应该是什么类型? LiveSubscription
或DisconnectedSubscription
?它既不是,也可能是IsLive
,它需要是一个或另一个。
关于与if
的比较:
在为LiveSubscription
分配新DisconnectedSubscription
实例或新Subscription
实例的代码中,正在发生对IClientSubscription
的隐式转换,因为编译器知道{ {1}}类型为Subscription
,IClientSubscription
和LiveSubscription
都可以隐式转换为该界面。
使用三元表达式的赋值有点不同,因为编译器首先尝试计算三元表达式,然后才尝试将其分配给DisconnectedSubscription
。这意味着编译器不知道三元表达式的结果必须是Subscription
类型。