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());
        }
    }
}

Error message:

Error CS0266 Cannot implicitly convert type 'ConsoleApplication12.Foo' to 'ConsoleApplication12.Bar'. An explicit conversion exists (are you missing a cast?) ConsoleApplication12 C:\Users\chliu\Documents\Visual Studio 2015\Projects\ConsoleApplication12\ConsoleApplication12\Program.cs

It seems "create a variable of derived class to refer an object by base class" is not allowed. Why?

1

1 Answer 1

2

This does not work without a cast :

Bar test = (Bar)new Foo();

Other way around it is working:

Foo test = new Bar();

It is because a Bar can have things that a Foo doesn't and it would result into an unexpected behavior if you try to access these on the Bar object created from a Foo.

To be a little more explicit, you can ask yourself a question to understand better casting:

Is Foo a Bar? If yes, then the cast from Foo to Bar will work like in the following example:

Foo actuallyBar = new Bar();

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

The other way of casting will always work because everytime you are asking if the Bar is a Foo the answer will be yes!

Foo foo = new Bar();//didn't even had to use explicit cast, because the compiler knows that Bar is a Foo
5
  • 1
    +1 for intuitive explanation of why one way works without problems and the other way needs a cast to tell the compiler that the programmer takes full responsibility for any problems down the line.
    – John D
    Commented Oct 26, 2016 at 5:21
  • When using "Bar test = (Bar)new Foo();", message : InvalidCastException was unhandled - "An unhandled exception of type 'System.InvalidCastException' occurred in ConsoleApplication12.exe" shows.
    – Mike Liu
    Commented Oct 27, 2016 at 7:00
  • 1
    @MikeLiu this is normal, you should consider that downcasting will not always succed. If you want to avoid the exception, you can do Foo test = new Bar() as Foo; and then if the cast does not succeed, test will be null. Commented Oct 27, 2016 at 7:18
  • @meJustAndrew can you explain more on the "It is because a Bar can have things that a Foo doesn't and it would result into an unexpected behavior if you try to access these on the Bar object created from a Foo."? Is it focused on error message? thank you.
    – Mike Liu
    Commented Oct 28, 2016 at 22:30
  • @MikeLiu you can tell me if know is more clear, and if not, I can improve it. Commented Oct 29, 2016 at 7:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.