C# 创建派生类的变量以引用基类的对象

C# 创建派生类的变量以引用基类的对象,c#,inheritance,new-operator,C#,Inheritance,New Operator,错误消息: 错误CS0266无法将类型“ConsoleApplication12.Foo”隐式转换为“ConsoleApplication12.Bar”。存在显式转换(是否缺少转换?)ConsoleApplication12 C:\Users\chliu\Documents\Visual Studio 2015\Projects\ConsoleApplication12\ConsoleApplication12\Program.cs 似乎“创建派生类的变量以按基类引用对象”是不允许的。为什么?如

错误消息:

错误CS0266无法将类型“ConsoleApplication12.Foo”隐式转换为“ConsoleApplication12.Bar”。存在显式转换(是否缺少转换?)ConsoleApplication12 C:\Users\chliu\Documents\Visual Studio 2015\Projects\ConsoleApplication12\ConsoleApplication12\Program.cs


似乎“创建派生类的变量以按基类引用对象”是不允许的。为什么?

如果没有演员阵容,这是行不通的:

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

namespace ConsoleApplication12
{
    public class Foo
    {
        public virtual bool DoSomething() { return false; }
    }

    public class Bar : Foo
    {
        public override bool DoSomething() { return true; }
    }

    public class Test
    {
        public static void Main()
        {
            Bar test = new Foo();
            Console.WriteLine(test.DoSomething());
        }
    }
}
另一种方法是:

Bar test = (Bar)new Foo();
这是因为
可能有
Foo
没有的东西,如果您试图在
对象上访问这些东西,就会导致意外行为

更明确一点,你可以问自己一个问题,以更好地理解铸造:

Foo
a
Bar
?如果是,则从
Foo
Bar
的转换将如以下示例所示:

Foo test = new Bar();
另一种铸造方法总是有效的,因为每次你问酒吧是不是一个Foo,答案都是肯定的

Foo actuallyBar = new Bar();

Bar = (Bar)actuallyBar; //this will succeed because actuallyBar is actually a Bar

如果没有强制转换,则无法执行此操作:

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

namespace ConsoleApplication12
{
    public class Foo
    {
        public virtual bool DoSomething() { return false; }
    }

    public class Bar : Foo
    {
        public override bool DoSomething() { return true; }
    }

    public class Test
    {
        public static void Main()
        {
            Bar test = new Foo();
            Console.WriteLine(test.DoSomething());
        }
    }
}
另一种方法是:

Bar test = (Bar)new Foo();
这是因为
可能有
Foo
没有的东西,如果您试图在
对象上访问这些东西,就会导致意外行为

更明确一点,你可以问自己一个问题,以更好地理解铸造:

Foo
a
Bar
?如果是,则从
Foo
Bar
的转换将如以下示例所示:

Foo test = new Bar();
另一种铸造方法总是有效的,因为每次你问酒吧是不是一个Foo,答案都是肯定的

Foo actuallyBar = new Bar();

Bar = (Bar)actuallyBar; //this will succeed because actuallyBar is actually a Bar

这是向下播放和向上播放这是向下播放和向上播放+1,用于直观解释为什么一种方式工作时没有问题,而另一种方式需要一个播放,以告诉编译器程序员对后续的任何问题承担全部责任。当使用“Bar test=(Bar)new Foo();”时,消息:InvalidCastException未处理-“在SoeleApple 12.exe”中出现的“Stale.ValueStudio异常”未处理的异常。“.Mikelu,这是正常的,您应该考虑到向下转换不会总是成功的。如果您想避免异常,可以执行<代码> FooTest=新Bar())。作为Foo;,如果强制转换没有成功,
test
将为
null
@meJustAndrew您可以解释更多关于“这是因为一个条可能有Foo没有的东西,如果您试图在从Foo创建的条对象上访问这些东西,它将导致意外行为。"? 它关注的是错误消息吗?谢谢。@MikeLiu如果知道的更清楚,你可以告诉我,如果不清楚,我可以改进它。+1可以直观地解释为什么一种方法可以毫无问题地工作,而另一种方法需要一个cast来告诉编译器程序员对任何问题负全责。当使用“Bar test=(Bar)new Foo();”时,消息:ValueCaseExtExchange未处理-“在SoeleApple 12.exe”中显示了一个未处理的类型“Stale.ValueStudiExtExchange”异常。如果您想避免异常,可以将
Foo test=new Bar()作为Foo
然后,如果强制转换未成功,
test
将为
null
@meJustAndrew您能否解释更多关于“这是因为一个条形图可能有一些Foo没有的东西,如果您试图在从Foo创建的条形图对象上访问这些东西,将会导致意外行为。”?它关注的是错误消息吗?谢谢。@MikeLiu如果知道的更清楚,你可以告诉我,如果不清楚,我可以改进它。