2012-12-15 20 views
6

Mam trudności ze zrozumieniem, w jaki sposób model kontenera/komponentu współdziała ze sobą w języku C#. Dostaję, jak komponent zawiera obiekt witryny, który zawiera informacje o kontenerze i komponencie. Ale załóżmy, że miałem następujący kod:Praca z System.ComponentModel

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

    }  

} 

To działa bez problemu, to definiuje pojemnik (podmiot) i składnik (pozycja), który jest zawarty w jego wnętrzu.

Jednakże, jeśli wywołuję p.Site.Container, to zwróci Entity, ale jako IContainer. To znaczy, musiałbym jawnie zrobić coś takiego jak (Console.WriteLine(p.Site.Container as Entity).Foo);, jeśli chcę uzyskać dostęp do Foo. Wydaje się to dość kłopotliwe.

Czy czegoś brakuje, czy jest lepszy sposób robienia tego, co chcę?

Odpowiedz

2

Nie brakuje niczego. Nie ma umowy dotyczącej interfejsu, który kontener może zawierać komponent. Jeśli chcesz ograniczyć jakie składniki mogą być dodawane do pojemnika można przeciążyć metodę Add i zrobić test typu składnika dodaje:

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

Więc w zasadzie, zamiast przyjąć dowolną IComponent, wymagają bardziej wyspecjalizowana wersja tego, czego szukam? Czy istnieje duża różnica między przykładem sprawdzającym typ, a nie mówiącym, wymagającym typowego typu z ograniczeniem typu? Zakładam, że tak jest, ale subtelność w tej chwili jest stracona. –

+1

Może być fajnie zastosować generyczne do tego scenariusza, ale niestety generics zostały wprowadzone w .NET 2.0, ale ComponentModel pochodzi z .NET 1.0, więc generics nie były dostępne. – Eilon

+0

@Eilon, dlaczego nie wystarczy użyć operatora 'is'. Byłoby znacznie czystsze niż "IsAssignableFrom". – Jordan