繁体   English   中英

C#中的元编程:自动ToString方法

[英]Metaprograming in C# : Automatic ToString Method

我有一些只用于包含数据的类。 例如

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

这代表一个地址。 就像我说的,它只包含数据。 没有方法(我知道界面在这里没有意义......)

现在我需要为所有这些Entity-Classes实现ToString,并且有很多它们。

我的问题是:C#中是否有一个元编程功能可以自动生成这种tostring方法? 我不想为这些类中的每一个编写样板代码。

或者,我也可以编写一个perl或python脚本来生成代码。 但我更喜欢直接在C#中使用它。

通常,您需要获取类的所有属性值并将它们组合成单个字符串。 这可以使用以下方法完成:

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

该功能称为反射。 最简单的例子是:

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

请微调它以满足您的要求。

正如您所看到的,想法是在基类中使用单个实现,以便所有后代自动继承相同的行为。

语言中没有内置功能可以自动执行此操作,但您可以使用框架中的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框架和反射,您将能够创建一个与您手动编写代码一样高效的委托。

你可以使用它自己的反射,但性能的提升很快就会成为一个问题。

有一个用于自动生成ToString的开源框架StatePrinter 它非常可配置,因此它应该满足您的需求。 内省代码可以在Introspection中找到

已经说过的简短版本:

public override string ToString()
{
    var propertyStrings = from prop in GetType().GetProperties()
                          select $"{prop.Name}={prop.GetValue(this)}";
    return string.Join(", ", propertyStrings);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM