4

I have the following classes:

public class BaseContainer
{
   public BaseItem item {get; set;}
}

public class ExtendedContainer : BaseContainer
{
   new public ExtendedItem item {get; set;}
}

public class BaseItem{
   public string Name { get; set; }
}

public class ExtendedItem : BaseItem
{
   public string Surname { get; set; }
}

Then I have the following instructions:

ExtendedItem ei = new ExtendedItem { Name = "MyName", Surname = "MySurname" };
ExtendedContainer ec = new ExtendedContainer { item = ei };
BaseContainer bc = ec;
string temp = bc.item.Name;  // bc.item is null, why?

Why bc.item is null? It shouldn´t because ExtendedItem is a subclass if BaseItem, but when I run the code it is null. Can anyone help me with this issue?

The reason I´m doing this is that I´m using MVC3 and I´m passing to partial views objects/models that are part of a similar structure, and I normally just need the properties in the base class.

Thanks in advance.

UPDATE

Jon is right, I´m accessing different objects. What I did to fix it is to use constructors to set the item properties to the same object. Like this:

public class BaseContainer
{
    public BaseItem item {get; set;}
    public BaseContainer(BaseItem item)
    {
        this.item = item;
    }
}

public class ExtendedContainer : BaseContainer
{
    public ExtendedItem item {get; set;}

    public ExtendedContainer(ExtendedItem item) : base(item)
    {
        this.item = item;
    }
}

public class BaseItem{
    public string Name { get; set; }
}

public class ExtendedItem : BaseItem
{
    public string Surname { get; set; }
}

And then I just create the object:

    ExtendedItem ei = new ExtendedItem { Name = "MyName", Surname = "MySurname" };
    ExtendedContainer ec = new ExtendedContainer(ei);
    BaseContainer bc = ec;
    string temp = bc.item.Name;

it works now

Alfonso Muñoz
  • 1,609
  • 17
  • 24
  • Your question has already been answered but take a look at [Does C# support return type covariance?](http://stackoverflow.com/questions/5709034/does-c-sharp-support-return-type-covariance) for a slightly different perspective (assuming the property-setter didn't exist). Also consider the generic constraint `BaseContainer where T : BaseItem` as a solution. – Ani Jun 05 '12 at 15:10

2 Answers2

3

You've used the new keyword, which hides the original base property in BaseContainer.

When you instantiate ExtendedContainer, you're setting the new property on the child class rather than the original property on the base class.

Just remove the property from the child class and everything should work.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
3

You've got two entirely separate properties here, which can store different values.

You've set the ExtendedContainer.item property on the object, but you haven't set the BaseContainer.item property.

Imagine the two properties had entirely different names - you wouldn't expect setting one to change the other then, would you? Well as far as the CLR is concerned, the fact that the two properties have the name is merely a coincidence.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I understand what you said Jon. How can I adapt the code to work in that situation? Maybe adding a constructor that receives the ExtendedItem and assings it to the item property in the BaseContainer. What do you think? – Alfonso Muñoz Jun 05 '12 at 16:08
  • @AlfonsoMuñoz: It's not really clear what you're trying to achieve, to be honest. The problem is that any other code can *also* reassign `BaseContainer.item`... – Jon Skeet Jun 05 '12 at 16:18
  • Yep, that is it. I used constructors to set the references to the same object. You are right when you said that in the original code "item" properties point to different objects. I´ll update the initial code to reflect how a fixed it. thanks – Alfonso Muñoz Jun 05 '12 at 16:19