2013-03-06 17 views
5

Ich habe einige Klassen, die nur dazu dienen, Daten zu enthalten. Zum BeispielMetaprogrammierung in C#: Automatische ToString-Methode

public class EntityAdresse : IEntityADRESSE 
{ 
    public string Name1 { get; set; } 
    public string Strasse { get; set; } 
    public string Plz { get; set; } 
    public string Ort { get; set; } 
    public string NatelD { get; set; } 
    public string Mail { get; set; } 
    public int Id_anrede { get; set; } 
    public string Telefon { get; set; } 
    public int Id_adr { get; set; } 
    public int Cis_adr { get; set; } 
} 

Dies ist eine Adresse. Wie gesagt, es enthält nur Daten. Keine Methoden (Ich weiß, dass die Schnittstelle hier keinen Sinn macht ...)

Jetzt muss ich ToString für all diese Entity-Klassen implementieren und es gibt eine Menge von ihnen.

Meine Frage ist: Gibt es eine Metaprogrammierungsfunktion in C#, die diese Methode automatisch generiert? Ich möchte für jede dieser Klassen keinen Code schreiben.

Alternativ könnte ich auch ein Perl oder Python-Skript schreiben, um den Code zu generieren. Aber ich bevorzuge es direkt in C#.

Antwort

7

Im Allgemeinen müssen Sie alle Eigenschaftswerte Ihrer Klasse abrufen und zu einer einzigen Zeichenfolge kombinieren. Dies kann unter Verwendung des folgenden Ansatzes erfolgen:

public override string ToString() 
{ 
    PropertyDescriptorCollection coll = TypeDescriptor.GetProperties(this); 
    StringBuilder builder = new StringBuilder(); 
    foreach(PropertyDescriptor pd in coll) 
    { 
     builder.Append(string.Format("{0} : {1}", pd.Name , pd.GetValue(this).ToString())); 
    } 
    return builder.ToString(); 
} 
+0

gefunden werden. Wahrscheinlich muss er auch den Namen der Eigenschaft anzeigen. –

+0

aktualisiert .... Ich habe hier Immobiliennamen hinzugefügt. – platon

+0

@platon Sie könnten die Antwort mit einer 'Null' Prüfung auf 'pd.GetValue (this)' aktualisieren. Ich bekam in diesem Fall einen NullPointer auf dem toString. – FrailWords

3

Die Funktion heißt Reflexion. Ein einfaches Beispiel wäre:

public class EntityBase 
    { 
     public override string ToString() 
     { 
      StringBuilder sb = new StringBuilder(); 

      foreach (var property in this.GetType().GetProperties()) 
      { 
       sb.Append(property.GetValue(this, null)); 
      } 

      return sb.ToString(); 
     } 
    } 

    public class TheEntity : EntityBase 
    { 
     public string Foo { get; set; } 
     public string Bar { get; set; } 
    } 

Bitte fein abstimmen, um Ihre Anforderungen zu erfüllen.

Wie Sie sehen, ist die Idee, eine einzelne Implementierung in einer Basisklasse zu haben, so dass alle Nachkommen automatisch das gleiche Verhalten erben.

+0

Das gibt mir nicht den Namen der Eigenschaften, richtig? – Luke

+0

'sb.AppendFormat (" {0} {1} ", property.Name, property.GetValue (this, null));' –

+0

Guter Job, aber ... Sie können in diesem Fall nicht mehr als EntityBase erweitern – boctulus

1

In der Sprache ist kein Feature eingebaut, um dies automatisch zu tun, aber Sie könnten eine Bibliothek schreiben, um dies mit den Expression Features im Framework zu tun, um eine Funktion dafür zu erzeugen.

Sie würden eine Funktion wie diese:

Func<T,string> GenerateToString<T>() 

Und Sie in Ihrer Klasse haben so etwas wie diese:

public class EntityAdresse : IEntityADRESSE 
{ 
    private static readonly Func<EntityAdresse,string> s_ToString=Generator.GenerateToString<EntityAdresse>(); 

    public string Name1 { get; set; } 
    public string Strasse { get; set; } 
    public string Plz { get; set; } 
    public string Ort { get; set; } 
    public string NatelD { get; set; } 
    public string Mail { get; set; } 
    public int Id_anrede { get; set; } 
    public string Telefon { get; set; } 
    public int Id_adr { get; set; } 
    public int Cis_adr { get; set; } 

    public override ToString() 
    { 
     return s_ToString(this); 
    } 
} 

Die Herausforderung GenerateToString schreibt. Mit dem Expression Framework und der Reflektion können Sie einen Delegaten erstellen, der genauso effizient ist, als hätten Sie den Code von Hand geschrieben.

Sie könnten die Reflexion selbst verwenden, aber der Leistungseinbruch wird bald ein Problem werden.

0

Für die automatische ToString-Generierung gibt es ein Open-Source-Framework StatePrinter. Es ist sehr konfigurierbar, so dass es auf Ihre Bedürfnisse eingehen sollte. Der Introspektionscode kann unter Introspection