寻找有关差异问题的解释

Dav*_*ave 1 c# covariance variance

......毕竟,这可能实际上不是一个方差问题.当我编译我的代码时,Visual Studio会给我以下错误:

无法确定条件表达式的类型,因为'ClassA'和'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>() {}
    }
}
Run Code Online (Sandbox Code Playgroud)

问题在于:

_ac = which ? new DerivedClass1() : new DerivedClass2();
Run Code Online (Sandbox Code Playgroud)

如果我使用内联if,我会得到那个可怕的编译器错误.但是,如果我改为使用它:

if( which)
    _ac = new DerivedClass1();
else 
    _ac = new DerivedClass2();
Run Code Online (Sandbox Code Playgroud)

我的代码编译得很好.

任何人都可以解释是什 我一直认为这两者是等价的.谢谢!

Dan*_*ite 7

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

first_expression和second_expression的类型必须相同,或者从一种类型到另一种类型必须存在隐式转换.

DerivedClass1和之间没有隐式转换DerivedClass2- 它只能通过存在的基类.运算符的规范并没有说它在分配中查找结果值类型,因此编译器正在执行它的设计目的.

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