2015-09-04 74 views
1

......毕竟,这实际上可能不是一个变异问题。当我编译代码时,Visual Studio就会给我下面的错误:寻找有关变化问题的解释

Type of conditional expression cannot be determined because there is no implicit conversion between 'ClassA' and 'ClassB'

我在这里这个错误读了,它肯定听起来这是不可能的,我可以用抽象类作为接口等,合同使用派生类代替它们的基类。为了使事情变得更简单,我编写了一些模拟我实际代码关系的测试类。请考虑以下几点:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace AbstractClassImplicitConversion { 
    class Program { 
     static void Main(string[] args) { 
      StartClass temp = new StartClass(); 
     } 
    } 

    public class StartClass 
    { 
     public AbstractClass _ac { get; private set; } 

     public StartClass() 
     { 
      bool which = true; 
      // this block will compile 
      /* 
      if(which) 
       _ac = new DerivedClass1(); 
      else 
       _ac = new DerivedClass2(); 
      */ 
      // this block will not compile 
      _ac = which ? new DerivedClass1() : new DerivedClass2(); 
     } 
    } 

    public interface SomeInterface 
    { 
     void SiFoo(); 
    } 

    public abstract class InnerAbstractClass 
    { 
     public abstract void IacFoo(); 
    } 

    public abstract class AbstractClass : InnerAbstractClass, SomeInterface 
    { 
     public override void IacFoo() { 

     } 

     public void SiFoo() { 

     } 

     public abstract void OverrideMe(); 
     public abstract void OverrideMeToo<T>(); 
    } 

    public class DerivedClass1 : AbstractClass 
    { 
     public override void OverrideMe() {} 
     public override void OverrideMeToo<T>() {} 
    } 

    public class DerivedClass2 : AbstractClass 
    { 
     private int _blah; 
     public override void OverrideMe() {} 
     public override void OverrideMeToo<T>() {} 
    } 
} 

的问题是与线:

_ac = which ? new DerivedClass1() : new DerivedClass2(); 

如果我使用内联如果,我会得到可怕的编译器错误。但是,如果我改用这个:

if(which) 
    _ac = new DerivedClass1(); 
else 
    _ac = new DerivedClass2(); 

我的代码编译得很好。

任何人都可以解释是什么原因造成的?我一直认为这两者是等同的。谢谢!

+1

你可以通过转换到基类来解决这个问题。 – crashmstr

+0

虽然这是一个很好看的问题,但我没有看到它与一旦你可能已经看过的情况有什么不同。版本“为什么两个兄弟派生类之间没有隐式转换”可能是很好的非重复选择,但我怀疑你已经知道了答案。还有其他答案,比如http://stackoverflow.com/a/202296/477420,它可能更好,但所有内容基本上与Daniel A. White的好答案一样。 –

+0

附注:考虑更新你的帖子,题目是关于“三元/条件运算符” - 所以它可能是未来搜索的好路标。 –

回答

7

这仅仅是语言标准的定义方式:

Either the type of first_expression and second_expression must be the same, or an implicit conversion must exist from one type to the other.

DerivedClass1DerivedClass2之间不存在隐式转换 - 它只能通过存在的基类。运算符的规范没有说它在赋值时会查看结果值类型,因此编译器正在执行它设计的任务。

来源:https://msdn.microsoft.com/en-us/library/ty67wk28.aspx

+0

感谢您的链接! – Dave

+0

@Dave随时! –

1

我认为你需要更改代码如下得到你要寻找的效果:

_ac = which ? (new DerivedClass1() as AbstractClass) : (new DerivedClass2() as AbstractClass); 

希望这有助于!

+2

'as'在这里是过度杀伤。改为使用一元'(Type)'。 –