C# .NET 6中HtmlElement类ToString()方法的优雅实现咨询
优化HtmlElement的ToString()实现方案
针对需求,这里提供几种更优雅的实现方式,既能避免重复的空值判断逻辑,也能兼顾扩展性:
方式一:用LINQ简化现有逻辑(适合属性数量少的场景)
直接把属性和对应的HTML属性名映射成键值对,通过LINQ过滤非空值后拼接,代码更简洁:
public class HtmlElement { public string Prop1 { get; set; } public string Prop2 { get; set; } public string Prop3 { get; set; } public override string ToString() { var attributes = new Dictionary<string, string?> { { "prop1", Prop1 }, { "prop2", Prop2 }, { "prop3", Prop3 } } .Where(kv => !string.IsNullOrEmpty(kv.Value)) .Select(kv => $" {kv.Key}=\"{kv.Value}\""); return $"<htmlElement{string.Concat(attributes)}></htmlElement>"; } }
方式二:自定义属性+反射(适合扩展场景)
如果后续要新增更多属性,用自定义注解标记需要转成HTML属性的字段,配合反射自动处理,不用每次修改ToString逻辑:
1. 定义自定义属性
[AttributeUsage(AttributeTargets.Property)] public class HtmlAttributeAttribute : Attribute { public string AttributeName { get; } public HtmlAttributeAttribute(string attributeName) { AttributeName = attributeName; } }
2. 修改HtmlElement类
public class HtmlElement { // 用自定义注解标记属性对应的HTML属性名 [HtmlAttribute("prop1")] public string Prop1 { get; set; } [HtmlAttribute("prop2")] public string Prop2 { get; set; } [HtmlAttribute("prop3")] public string Prop3 { get; set; } public override string ToString() { var attributes = GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.GetCustomAttribute<HtmlAttributeAttribute>() != null) .Select(p => { var attr = p.GetCustomAttribute<HtmlAttributeAttribute>(); var value = p.GetValue(this) as string; return !string.IsNullOrEmpty(value) ? $" {attr.AttributeName}=\"{value}\"" : string.Empty; }) .Where(s => !string.IsNullOrEmpty(s)); return $"<htmlElement{string.Concat(attributes)}></htmlElement>"; } }
3. 优化反射性能(可选)
如果担心反射重复执行的性能问题,可以在静态构造函数中缓存需要处理的属性信息:
public class HtmlElement { // 静态缓存属性和对应的注解,只初始化一次 private static readonly IEnumerable<(PropertyInfo Prop, HtmlAttributeAttribute Attr)> _htmlProperties; static HtmlElement() { _htmlProperties = typeof(HtmlElement) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => (Prop: p, Attr: p.GetCustomAttribute<HtmlAttributeAttribute>())) .Where(x => x.Attr != null) .ToList(); } [HtmlAttribute("prop1")] public string Prop1 { get; set; } [HtmlAttribute("prop2")] public string Prop2 { get; set; } [HtmlAttribute("prop3")] public string Prop3 { get; set; } public override string ToString() { var attributes = _htmlProperties .Select(x => { var value = x.Prop.GetValue(this) as string; return !string.IsNullOrEmpty(value) ? $" {x.Attr.AttributeName}=\"{value}\"" : string.Empty; }) .Where(s => !string.IsNullOrEmpty(s)); return $"<htmlElement{string.Concat(attributes)}></htmlElement>"; } }
内容的提问来源于stack exchange,提问作者CrazyEight
相关产品推荐
相关产品推荐

