2012-12-15 2 views
6

Ich habe ein wenig Schwierigkeiten zu verstehen, wie das Container/Komponentenmodell in C# miteinander interagiert. Ich bekomme, wie die Komponente ein Site-Objekt enthält, das Informationen über Container und Komponente enthält. Aber ich nehme an den folgenden Code hatte:Mit System.ComponentModel arbeiten

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");    

    }  

} 

Dies ohne Problem funktioniert, ist es definiert einen Container (Entity) und eine Komponente (Position), die darin enthalten ist.

Wenn ich jedoch p.Site.Container aufrufen, wird es Entity zurückgeben, aber als IContainer. Das heißt, ich müsste explizit etwas wie (Console.WriteLine(p.Site.Container as Entity).Foo); machen, wenn ich auf Foo zugreifen wollte. Das erscheint ziemlich umständlich.

Fehle ich etwas, oder gibt es einen besseren Weg zu tun, was ich will?

Antwort

2

Sie verpassen nichts. Es gibt keinen Schnittstellenvertrag darüber, in welchem ​​Container sich eine Komponente befinden kann. Wenn Sie einschränken möchten, welche Art von Komponenten in den Behälter gegeben werden, können Sie die Add-Methode überlasten und eine Überprüfung der Art der Komponente tun hinzugefügt werden:

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); 
    } 
} 
+0

Also im Grunde nicht akzeptieren jede IComponent, erfordern ein spezialisiertere Version davon, was ich suche? Jetzt gibt es einen großen Unterschied zwischen Ihrem Beispiel für Typ, im Gegensatz zu sagen, erfordert einen generischen Typ mit einem Typ-Constraint? Ich würde annehmen, dass es da ist, aber die Subtilität ist im Moment für mich verloren. –

+1

Es wäre nett, Generics auf dieses Szenario anzuwenden, aber leider wurden Generics in .NET 2.0 eingeführt, aber ComponentModel stammt aus .NET 1.0, daher waren Generics nicht verfügbar. – Eilon

+0

@Eilon, warum nicht einfach den "is" -Operator verwenden. Es wäre viel sauberer als 'IsAssignableFrom'. – Jordan