2010-12-29 14 views
0

Dies ist für .net MVC-Projekt arbeite ich auf.net abstrakte Klasse und Reflexionen

ich die folgenden Klassen:

public abstract class TemplateBase 
{ 
    public abstract string TemplateName { get; } 
    public string RuntimeTypeName { get { return GetType().FullName; } } 
} 

und 2 Klassen, die von ihm erben:

public class TwoColumnTemplate : TemplateBase 
{ 
    public override string TemplateName { get { return "Two-column page"; } } 
    public AreaContainer LeftColumn { get; protected set; } 
    public AreaContainer RightColumn { get; protected set; } 

    public TwoColumnTemplate() 
    { 
     LeftColumn = new AreaContainer("Left column"); 
     RightColumn = new AreaContainer("Right column"); 
    } 
} 

    public class SingleColumnTemplate : TemplateBase 
{ 
    public override string TemplateName { get { return "Single-column page"; } } 
    public AreaContainer CenterColumn { get; protected set; } 

    public SingleColumnTemplate() 
    { 
     CenterColumn = new AreaContainer("Center column"); 
    } 
} 

und eine Content Klasse, die für die Anzeige/Modifizieren HTML-Inhalt

public class ContentPage 
{ 
    public virtual int ContentPageId { get; set; } 

    public virtual string Title { get; set; } 

    public TemplateBase Template { get; set; } 
} 
verwendet wird

Jetzt die Frage. Ich habe ein Modell geschaffen, das Bindemittel Content bindet und ich tue, um die Daten zu meiner Action erhalten wie so:

 [HttpPost] 
    public ActionResult Edit(ContentPage row) 
    { 
     return this.View(row); 
    } 

Zeile jedoch die richtigen Daten hat ich da nicht nach links oder rechts Spalt Daten abstrakte Klasse Templatebase zugreifen kann . Zu clerify gibt es eine Möglichkeit, "row" -Objekt dynamisch zu einem korrekten Klasse (SingleColumn oder TwoColumn) -Typ zu werfen?

Anstelle von If/Else gibt es einen besseren Weg ?. Vielleicht mit Reflexionen? dank

 [HttpPost] 
    public ActionResult Edit(ContentPage row) 
    { 
     var sb = new StringBuilder(); 

    if (row.Template.RuntimeTypeName == "TwoColumn") 
    { 
     TwoColumnTemplate template = (TwoColumnTemplate)row.Template; 
    } 
    else 
    { 
     SingleColumnTemplate template = (SingleColumnTemplate)row.Template; 
    } 

     return this.View(row); 
    } 

Antwort

4

Sie brauchen nicht die RuntimeTypeName Eigenschaft überhaupt. Die korrekte Art, Typprüfung zu tun, würde etwas in der Art sein:

if (row.Template is TwoColumnTemplate) 
{ 
    TwoColumnTemplate template = (TwoColumnTemplate)row.Template; 
} 
else if (row.Template is SingleColumnTemplate) 
{ 
    SingleColumnTemplate template = (SingleColumnTemplate)row.Template; 
} 

Jedoch schreit dieses für korrekten OO Entwurf. Wenn Sie eine Hierarchie von Klassen haben und ständig testen, ob ein Objekt einer Klasse angehört, ist Ihr Klassenmodell stark beschädigt.

Vielleicht sollten Ihre Vorlagenklassen selbst ihre eigenen HTML- oder Zustandsobjekte über eine abstrakte Methode ausgeben? Das Typsystem gibt Ihnen alle Möglichkeiten, um dieses Problem zu lösen, ohne zu testen, ob ein Objekt von einem bestimmten Typ ist.

+0

können Sie bitte ein bisschen mehr erklären? "Vielleicht sollten Ihre Template-Klassen selbst ihre eigenen HTML- oder View-State-Objekte über eine abstrakte Methode ausgeben? Das Typsystem gibt Ihnen alle Möglichkeiten, dieses Problem zu lösen, ohne zu testen, ob ein Objekt von einem bestimmten Typ ist." – ShaneKm

+0

@Shane: Zum Beispiel, was auch immer Sie in diesen if/else-Blöcken tun, sollten Sie in eine Methode für die beiden entsprechenden Klassen verschieben und eine abstrakte Methode für diese beiden Methoden für die Basisklasse bereitstellen. Dann müssen Sie nicht wirklich wissen, mit welchem ​​Objekt Sie es zu tun haben. Es wäre hilfreich, den tatsächlichen Inhalt der if/else-Blöcke zu kennen, da der von Ihnen bereitgestellte Code nicht vollständig genug ist, um zu wissen, was Sie tun. – cdhowie

+0

ah. Ich habs. Vielen Dank. Das hat ein bisschen geholfen. – ShaneKm