views:

262

answers:

3

Hi, in the below example, what would happen?

class Base {
    public int abc = 3;
}

Class Derived : Base {
    public int abc = 2;
}

static void Main() {
   Derived blah = new Derived();
   Console.WriteLine(blah.abc);
}

I'm sure you would see '2' on your console, but what I'm reading (and seeing) opposes that...

Why would you see '3' instead of '2'? I thought members of derived classes 'hid' the same members of base classes...

A: 

Ignoring the obvious and numerous errors in your code :O, your assertion that "I'm sure you would see '2' on your console" is correct, you will, and I do!

You should really user

class Derived : Base {
    public new int abc = 2;
}

if hiding the inherited value is your intention

Paul Creasey
A: 

Of course you will see 2. Why did you think that you will see 3 ?

But you will get a warning:

'Derived.abc' hides inherited member 'Base.abc'. Use the new keyword if hiding was intended.

So you can solve it doing:

class Derived : Base {
    public new int abc = 2;
}
JCasso
+8  A: 

Well, you have a few compiler errors, but here is a corrected version based on your example.

class Base {
    public int abc = 3;
}

class Derived : Base {
    public int abc = 2;
} 

static void Main(string[] args)
{
    Derived foo = new Derived();
    Console.WriteLine(foo.abc);
    Base bar = new Derived();
    Console.WriteLine(bar.abc);
}

The first line will output a 2. The second line will output a 3. The reason why is because, unless you explicitly override a member of a base class, it will only apply to instances of the concrete class.

In your derived class, you're essentially using the new modifier keyword without explicitly using it. The new keyword hides a base member, however if the concrete class is cast as its base type, the new property doesn't get used and can't be accessed until it is "cast-down" to the concrete class again.

In the second example, the Derived class is cast as a Base, so it will use the Base abc property. If you were to use the override keyword, then the second line would also output a 2.

Edit: Keep in mind that in order to be allowed to use override on the Derived class, you need to mark Base.abc with the virtual keyword. Also, you can't make fields virtual. You need to use Properties to use the virtual keyword. You shouldn't be exposing fields to begin with though, so this is generally never a problem.

Dan Herbert
Beat me to it. Good answer!
Arjan Einbu
Well, I thought this ages ago but I always get:"error CS0106: The modifier 'override' is not valid for this item"
Motig
You need to add `virtual` to the base class' property in order to use `override` on a derived class.
Dan Herbert
@Dan: Just makes it worse: The modifier 'override' is not valid for this itemThe modifier 'virtual' is not valid for this item
Motig
Yeah. You can't make a field `virtual`. You should be using Properties instead of exposed fields. Making fields public is generally bad practice.
Dan Herbert