2016-10-26 9 views
0
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()); 
     } 
    } 
} 

エラーメッセージ:暗黙的に「ConsoleApplication12.Bar」にタイプ「ConsoleApplication12.Foo」を変換できませんは、基本クラスのオブジェクトを参照するために、派生クラスの変数を作成

エラーCS0266。明示的な変換は、(あなたがキャストが欠けている?)が存在しConsoleApplication12 C:「派生クラスの変数を作成すると思われるプロジェクト\ ConsoleApplication12 \ ConsoleApplication12 \ Program.csの\ Visual Studioの2015 \ \ Users \ユーザーchliuの\ドキュメント

基底クラスでオブジェクトを参照する "ことはできません。どうして?

+0

、これは一つの方法は問題なく動作し、他の方法は、キャストを必要とする理由の直感的な説明のために意気消沈-と-アップキャストhttp://stackoverflow.com/questions/1524197/downcast-and-upcast – pix

答えて

2

これは、キャストせずに動作しません:それは周り

Bar test = (Bar)new Foo(); 

他の方法が取り組んでいる:

Foo test = new Bar(); 

BarFooがないという事を持つことができ、それがなるのでそれはありますFooから作成されたBarオブジェクトでこれらのオブジェクトにアクセスしようとすると、予期しない動作が発生します。

もう少し明確にするためには、よりよい鋳造を理解するために自分自身に質問をすることができます。

FooBarですか? yesの場合、FooからBarへのキャストは、次の例のように動作する場合:

Foo actuallyBar = new Bar(); 

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

鋳造の他の方法は、常に動作します、あなたが求めている毎回のバーがfooである場合ので、答えはイエスになります!

Foo foo = new Bar();//didn't even had to use explicit cast, because the compiler knows that Bar is a Foo 
+1

+1ですプログラマが問題を完全に解決したことをコンパイラに伝える。 –

+0

"Bar test =(Bar)new Foo();"を使用すると、InvalidCastExceptionが処理されませんでした - "ConsoleApplication12.exeで 'System.InvalidCastException'型の未処理の例外が発生しました。 –

+1

@MikeLiuこれは正常ですが、ダウンキャスティングは必ずしも成功したとは限りません。例外を避けたい場合は、 'Foo test = new Bar()をFoo;'とすることができます。そして、キャストが成功しなかった場合、 'test'は' null'になります。 – meJustAndrew

関連する問題