2013-03-06 16 views
5

我有一些只用於包含數據的類。例如,C#中的元編程:自動ToString方法

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; } 
} 

這表示一個地址。就像我說的那樣,它只包含數據。沒有方法(我知道這裏的界面沒有意義...)

現在我需要爲所有這些實體類實現ToString,並且有很多它們。

我的問題是:是否有一個C#中的元編程功能,它會自動生成這個tostring方法?我不想爲每個這些類編寫鍋爐板代碼。

或者我也可以編寫一個perl或python腳本來生成代碼。但我更喜歡直接在C#中執行。

回答

7

通常,您需要獲取類的所有屬性值並將它們合併爲一個字符串。這可以使用以下方法完成:

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

它也必須顯示該屬性的名稱。 – 2013-03-06 10:19:15

+0

更新....我在這裏添加屬性名稱。 – platon 2013-03-06 10:22:33

+0

@platon你可以在'pd.GetValue(this)'上用'null'檢查來更新答案。在那種情況下,我在toString上得到了一個N​​ullPointer。 – FrailWords 2015-11-10 10:32:36

3

該功能稱爲反射。最簡單的例子是:

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; } 
    } 

請微調它以滿足您的要求。

正如你所看到的想法是在基類中有一個實現,以便所有的下降自動繼承相同的行爲。

+0

這不給我屬性的名稱,對吧? – Luke 2013-03-06 10:21:39

+0

'sb.AppendFormat(「{0} {1}」,property.Name,property.GetValue(this,null));' – 2013-03-06 10:44:22

+0

好的工作,但是......在這種情況下你不能擴展超過EntityBase – boctulus 2015-04-10 23:47:50

1

這種語言沒有內置功能可以自動執行此操作,但是您可以使用框架中的Expression功能編寫庫來執行此操作,以生成執行此功能的功能。

你必須像這樣的功能:

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

而在你的類,你有這樣的事情:

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

所面臨的挑戰是寫GenerateToString。使用Expression框架和反思,您可以創建一個與手動編寫代碼一樣高效的委託。

你可以使用它自己的反射,但性能命中很快就會開始成爲一個問題。

0

有一個用於自動生成ToString的開源框架StatePrinter。這是非常可配置的,所以它應該滿足您的需求。內省代碼可在Introspection