Ternary Expression with Interfaces as a Base Class
我正在尝试创建三元表达式,但出现以下错误
"无法确定条件表达式的类型,因为LiveSubscription和DisconnectedSubscription之间没有隐式转换"
相同的逻辑在if语句中有效,但我想了解为什么它在三元表达式中不起作用-
这是我要执行的操作的要点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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,但我想先了解发生了什么问题!
您需要将至少一个操作数强制转换为
1 2 3 | Subscription = (IsLive) ? (IClientSubscription)new LiveSubscription() : new DisconnectedSubscription(); |
原因是三元表达式是由操作数确定的某种类型。基本上,它尝试将第二个操作数转换为第一个操作数的类型,反之亦然。两者都在这里失败,因为
编译器不会检查两者是否共享相同的基本类型。
尝试在评论中回答您的问题:
不,三元表达式不是某种对象,但是三元表达式是赋值的右手部分。赋值的每个右手部分表达式都具有某种类型,否则将无法将该表达式分配给左侧的变量。
例子:
-
var x = Guid.NewGuid() 右侧表达式(
Guid.NewGuid() )的类型为Guid ,因为方法NewGuid() 返回Guid 。 -
var x = y.SomeMethod() 右侧表达式的类型为
SomeMethod() 的返回类型。 -
var x = IsLive ?"a" : 1 这显然是无效的,不是吗?
x 应该是什么类型?string 还是int ?
这将导致产生与您的代码完全相同的错误消息。 -
您的示例有所更改:
1
2var subscription = (IsLive) ? new LiveSubscription()
: new DisconnectedSubscription();注意
subscription 之前的var ,我们现在初始化一个新变量,而不是现有变量。我认为即使在这里,问题也很明显:subscription 应该是什么类型?LiveSubscription 或DisconnectedSubscription ?两者都不可以,因为取决于IsLive ,它必须是一个。
关于与
在您的代码中,将新的
三元表达式的分配有些不同,因为编译器首先尝试评估三元表达式,然后才尝试将其分配给