0

How do I get the base class data into the child class object when using keyword as. I tried the below code but it returns null data.

class BaseC
{
    public int BaseId { get; set; }
    public string BaseName { get; set; }
}

class DerivedC: BaseC
{
    public int DerivedId { get; set; }
    public string DerivedName { get; set; }
}
class Program
{
    static void Main(string[] args)
    {

        BaseC baseC = new BaseC();
        baseC.BaseId = 1;
        baseC.BaseName = "base class name ";
        var derivedC = baseC as DerivedC;
    }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
team sg
  • 21
  • 1
  • 7
    Because the pure `Basec` you created is NOT a `DerivedC` so `as` will return `null since it can't be cast. Downcasting is not allowed in C#. What are you trying to accomplish? – D Stanley Sep 26 '14 at 14:02
  • A `BaseC` object is not always a `DerivedC` object (the other way around it is). You created just a `BaseC` object and not a `DerivedC` object. You try to do a narrowing cast (BaseC to DerivedC), while only a widening cast would work (DerivedC to BaseC). – Styxxy Sep 26 '14 at 14:04
  • Derived C inherits from BaseC and you want to treat BaseC as DeviedC... See the problem? Also, why using var? var is an undefined type use it in a linq for example – user28470 Sep 26 '14 at 14:04
  • 1
    Have a look at [Is it really downcasting not possible? It is working fine for me](http://stackoverflow.com/questions/17956475/is-it-really-downcasting-not-possible-it-is-working-fine-for-me) – huMpty duMpty Sep 26 '14 at 14:05
  • 3
    @user28470 `var` does not mean "undefined" - it means "let the compiler infer the type from the declaration". It's perfectly fine to use outside of Linq. In this case the compiler would use `DerivedC` as the _inferred_ type. – D Stanley Sep 26 '14 at 14:07
  • Yes, so var is undefined type it gets the type of what will it be used for – user28470 Sep 26 '14 at 14:09
  • 1
    @user28470 No, "undefined" means "I can use it for anything", which is not what `var` means - so you can't say `var x = 1; x = "one";` because `x` is an `int`, not a `string` or "variant". – D Stanley Sep 26 '14 at 14:42

4 Answers4

5

That's right as behaivour:

Your code (simplified):

 BaseC baseC = new BaseC();

 // null: result is a BaseC instance and not DerivedC one
 DerivedC result = baseC as DerivedC;

Reversed code (probably, what you expected to see):

 BaseC baseC = new DerivedC(); // <- Now, DerivedC instance created

 // not null: result is in fact a DerivedC instance: new DerivedC()
 DerivedC result = baseC as DerivedC; 

 // not null: DerivedC is inherired from BaseC
 // and that's why any DerivedC instances are BaseC instances as well
 BaseC result2 = baseC as BaseC; 
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
4

This won't work. Replace BaseC with Animal and DerivedC with Cow and you'll see why.

The runtime cannot create a Cow from an instance of Animal, as there's information missing. This will work:

BaseC baseC = new DerivedC();

Because the instance actually is a DerivedC.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
0

baseC is not an instance of DerivedC, so the as operator will always return null.

It would work however, if you changed the first line of Main to this:

BaseC baseC = new DerivedC();
RobSiklos
  • 8,348
  • 5
  • 47
  • 77
0

As for a practical solution (perhaps you were already doing this before you tried out the as keyword, but I figured I'd throw it out there):

If all you have available is a base instance (and you can't change that for some reason), and you want to populate the derived instance, you might consider adding a constructor that accepts the base class as a parameter:

class DerivedC : BaseC
{
    public DerivedC() {}  // req'd so you can still create an instance without a BaseC

    public DerivedC(BaseC baseC)
    {
        BaseId = baseC.BaseId;
        BaseName = baseC.BaseName;
    }

    public int DerivedId { get; set; }
    public string DerivedName { get; set; }
}

Then call it like this:

var derivedC = new DerivedC(baseC);

At least that cuts down on code duplication, so you're not manually assigning values in multiple places.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165