C# CS0173具有不同返回类型的三元上的编译错误
考虑这个例子:C# CS0173具有不同返回类型的三元上的编译错误,c#,oop,C#,Oop,考虑这个例子: using System.IO; using System; class A{} class B : A{} class C : A{} class Program { static void Main() { GetSomething1(true); } static A GetSomething1(bool oneOrAnother) { return oneOrAnother ? new B()
using System.IO;
using System;
class A{}
class B : A{}
class C : A{}
class Program
{
static void Main()
{
GetSomething1(true);
}
static A GetSomething1(bool oneOrAnother)
{
return oneOrAnother ? new B() : new C(); // throws a compile error
}
static A GetSomething2(bool oneOrAnother)
{
return oneOrAnother ? (A)(new B()) : new C(); // no error
}
static A GetSomething3(bool oneOrAnother)
{
return oneOrAnother ? new B() : (A)(new C()); // no error
}
static A GetSomething4(bool oneOrAnother)
{
return oneOrAnother ? (A)(new B()) : (A)(new C()); // no error
}
}
GetSomething1中的三元数生成
错误CS0173:无法确定条件表达式的类型,因为'B'和'C'之间没有隐式转换。
我无法理解为什么B和C都可以完美地转换为A(它们从A扩展而来),并且在进一步的示例中,仅显式转换其中一个就足以获得三元工作三元表达式的规则是两个可能的结果必须是相同的类型,或者其中一个可以安全地抛给另一个。编译器不会去寻找一个安全的第三个基类,它可以同时用于这两个基类。因此,您必须指定这两个表达式中的一个是基类,比如
?(A) new B():new C()
,这是Eric Lippert为C#9提出的:“如果两种类型都不属于另一种类型,那么请注意,我们不会试图找到“最近的包含类型”。有趣的是,Java允许这样做……据我所知,C#9建议,他们打开了一些表达式,允许在存在目标类型时自动转换为目标类型。在问题中的代码中,第一个表达式的目标类型将是A
,并且由于B
和C
都可以强制转换为A
,因此这是允许的。您仍然不能执行var x=one或other吗?新的B():新的C()代码>因为没有要定位的类型,但是您可以执行A x=…
。基本上,如果我理解正确,您可以将表达式的使用方式添加到混合中,以及使用预期的类型。三元表达式的规则是,两个可能的结果必须是相同的类型,或者其中一个可以安全地转换为另一个。编译器不会去寻找一个安全的第三个基类,它可以同时用于这两个基类。因此,您必须指定这两个表达式中的一个是基类,比如?(A) new B():new C()
,这是Eric Lippert为C#9提出的:“如果两种类型都不属于另一种类型,那么请注意,我们不会试图找到“最近的包含类型”。有趣的是,Java允许这样做……据我所知,C#9建议,他们打开了一些表达式,允许在存在目标类型时自动转换为目标类型。在问题中的代码中,第一个表达式的目标类型将是A
,并且由于B
和C
都可以强制转换为A
,因此这是允许的。您仍然不能执行var x=one或other吗?新的B():新的C()代码>因为没有要定位的类型,但是您可以执行A x=…
。基本上,如果我理解正确,您可以将表达式的使用方式添加到混合中,以及使用预期的类型。