6

I am having a bit of difficulty in understanding how the Container/Component model interacts with each other in C#. I get how the Component contains a Site object which has information about Container and Component. But, suppose I had the following code:

using System;
using System.ComponentModel;

public class Entity : Container {
    public string Foo = "Bar";
}

public class Position : Component {
    public int X, Y, Z;    
    public Position(int X, int Y, int Z){
        this.X = X;
        this.Y = Y;
        this.Z = Z;
    }
}

public class Program {

    public static void Main(string[] args) {

        Entity e = new Entity();
        Position p = new Position(10, 20, 30);

        e.Add(p, "Position");            

    }    

}

This works without issue, it defines a Container (Entity) and a Component (Position) that is contained inside it.

However, if I invoke p.Site.Container, it will return Entity, but as IContainer. That is, I would have to explicitly do something like (Console.WriteLine(p.Site.Container as Entity).Foo); if I wanted to access Foo. This seems quite cumbersome.

Am I missing something, or is there a better way to do what I want?

Kyle Baran
  • 1,793
  • 2
  • 15
  • 30

1 Answers1

2

You're not missing anything. There is no interface contract regarding what container a component can be inside. If you want to restrict what kind of components can be added to the container you can overload the Add method and do a check of the type of component being added:

public class Entity : Container {
    public string Foo = "Bar";

    public virtual void Add(IComponent component) {
        if (!typeof(Position).IsAssignableFrom(component.GetType())) {
            throw new ArgumentException(...);
        }
        base.Add(component);
    }
}
Eilon
  • 25,582
  • 3
  • 84
  • 102
  • So basically, rather than accept any IComponent, require a more specialized version of it which has what I'm looking for? Now is there a big difference between your example checking for type, as opposed to say, requiring a generic type with a type constraint? I would assume there is, but the subtlety is lost on me at the moment. – Kyle Baran Dec 15 '12 at 16:59
  • 1
    It might be nice to apply generics to this scenario but unfortunately generics were introduced in .NET 2.0 but ComponentModel is from .NET 1.0 so generics weren't available. – Eilon Dec 15 '12 at 17:01
  • @Eilon, why not just use the `is` operator. It would be much cleaner than `IsAssignableFrom`. – Jordan Oct 20 '15 at 17:36