[英]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.