......毕竟,这可能实际上不是一个方差问题。当我编译我的代码时,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>() {}
}
}
问题出在以下几行:
_ac = which ? new DerivedClass1() : new DerivedClass2();
如果我使用内联if,我会得到那个可怕的编译器错误。但是,如果我改为使用它:
if( which)
_ac = new DerivedClass1();
else
_ac = new DerivedClass2();
我的代码编译得很好。
任何人都可以解释是什么原因造成的?我一直认为这两者是等价的。谢谢!
答案 0 :(得分:7)
这就是语言标准的定义方式:
first_expression和second_expression的类型必须相同,或者从一种类型到另一种类型必须存在隐式转换。
DerivedClass1
和DerivedClass2
之间没有隐式转换 - 它只能通过存在的基类进行转换。运算符的规范并未说明它会在赋值中查找结果值类型,因此编译器正在执行它的设计目标。
答案 1 :(得分:1)
我认为您需要更改代码,以获得您正在寻找的效果:
_ac = which ? (new DerivedClass1() as AbstractClass) : (new DerivedClass2() as AbstractClass);
希望这有帮助!