2015-09-04 4 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, которые могут быть приятнее, но все по сути то же самое, что и хороший ответ Дэниела А. Уайта. –

+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.

Там нет неявного преобразования между DerivedClass1 и DerivedClass2 - его только через базовый класс, который существует. Спецификация оператора не говорит о том, что он смотрит на результирующий тип значения в присваивании, поэтому компилятор делает то, что он предназначен.

Источник: 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

'как' здесь слишком много. вместо этого используйте унарный '(Type)'. –

 Смежные вопросы

  • Нет связанных вопросов^_^