Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么?:运算符要求显式强制转换?_C#_If Statement_Casting - Fatal编程技术网

C# 为什么?:运算符要求显式强制转换?

C# 为什么?:运算符要求显式强制转换?,c#,if-statement,casting,C#,If Statement,Casting,我有这段代码 StateMachine.State = string.IsNullOrEmpty(MyString) ? (IState) StateMachine.StateA : StateMachine.StateB; 我也可以这样写 if (string.IsNullOrEmpty(MyString)) StateMachine.State = StateMachine.StateA; el

我有这段代码

        StateMachine.State = string.IsNullOrEmpty(MyString) ?
            (IState) StateMachine.StateA : StateMachine.StateB;
我也可以这样写

        if (string.IsNullOrEmpty(MyString))
            StateMachine.State = StateMachine.StateA;
        else
            StateMachine.State = StateMachine.StateB;
State
类型为
IState
StateA
StateB
都实现了
IState

在第一个代码段中,编译器要求显式强制转换,而在第二个代码段中则不需要显式强制转换。为什么在第一个示例中需要它

编辑: 建议的重复问题并不完全涵盖我的问题。我的问题是关于对象和接口,而另一个问题是关于基本数据类型和常量。 特别是格扎尔卡特关于声明的建议非常有价值


阅读关于建议的重复问题的答案永远不会为我指明方向。

当在表达式
x中时会发生这种情况?a:b
a和b返回不同的类型

看看:

double a = 5;
decimal b = 4;
var z = x ? a : b;
Z的类型应该是什么?即使A和B是某种兼容类型,例如,
int
long
,编译器应该如何猜测返回什么?结果应该是int还是long

在您的情况下,最有可能的是StateA是“classA”类型,StateB是“classB”类型。这两个类都实现了IState,因此简单的赋值是有效的,但是当您将它放入
?:
运算符时,编译器无法决定
?:
运算符的结果应该是
classA
还是
classB

是的,我没有错:编译器甚至不考虑istTATE。为什么?因为classA和classB可能有更多的通用接口或基本类型。它们可以同时实现IState、IEnumerable或<代码>对象处于极限。编译器应该选择哪个公共基类?很难决定,所以它不会去猜测

有一个非常简单的解决方案,除了你自己已经发现的显式转换。只需更改StateA和StateB字段/属性的返回类型

现在,您可能已经:

class StateMachine
{
    public ClassA StateA {get .. }
    public ClassB StateB {get .. }
}
由于两者都实现IState,只需将其更改为:

class StateMachine
{
    public IState StateA {get .. }
    public IState StateB {get .. }
}

此外,后一种方式(仅通过接口提供状态实例)可能更可取,因为如果状态机属性是一个“状态库”,可以从中选择,那么,选择这些状态的代码位置可能不知道这些状态的确切实现类型,但这当然不是必需的,取决于您的设计。

就是这样!一个很好的建议,将我的StateA和StateB声明更改为IState的声明。非常感谢你!