代码之家  ›  专栏  ›  技术社区  ›  chillitom Cee McSharpface

是否有一个等价于Java的ToStringBuilder for C#?一个好的C版本有什么特点?

  •  14
  • chillitom Cee McSharpface  · 技术社区  · 15 年前

    ToStringBuilder 帮助创建toString()实现。

    有人知道C#有一个像样的免费实现吗?有没有更好的选择我不知道?

    如果没有自由实现的话,我想这个问题就更像是一个

    在我的脑海里:

    • 它可以提供反射和手动创建ToString字符串。

    • 如果它能利用表达式树,那就太酷了。

     public override string ToString()
       {
          return new ToStringBuilder<Foo>(this)
             .Append(t => t.Id)
             .Append(t => t.Name)
             .ToString();
       }
    

    它将返回:

     "Foo{Id: 1, Name: AName}"
    
    • 它可以使用System.Reflection.Emit预编译ToString委托。

    更新

    只是澄清一下,对于StringBuilder来说,ToStringBuilder是一个不同的生物。。我正在寻找类似于apachecommon的ToStringBuilder功能的东西,它具有多行格式、不同样式和基于反射的ToString创建等特性。谢谢

    更新2

    here .

    8 回复  |  直到 7 年前
        1
  •  13
  •   Dan Tao    15 年前

    :好的,您想使用反射,这样就不必键入属性名。我想这会让你得到你想要的:

    // forgive the mangled code; I hate horizontal scrolling
    public sealed class ToStringBuilder<T> {
        private T _obj;
        private Type _objType;
        private StringBuilder _innerSb;
    
        public ToStringBuilder(T obj) {
            _obj = obj;
            _objType = obj.GetType();
            _innerSb = new StringBuilder();
        }
    
        public ToStringBuilder<T> Append<TProperty>
        (Expression<Func<T, TProperty>> expression) {
    
            string propertyName;
            if (!TryGetPropertyName(expression, out propertyName))
                throw new ArgumentException(
                    "Expression must be a simple property expression."
                );
    
            Func<T, TProperty> func = expression.Compile();
    
            if (_innerSb.Length < 1)
                _innerSb.Append(
                    propertyName + ": " + func(_obj).ToString()
                );
            else
                _innerSb.Append(
                    ", " + propertyName + ": " + func(_obj).ToString()
                );
    
            return this;
        }
    
        private static bool TryGetPropertyName<TProperty>
        (Expression<Func<T, TProperty>> expression, out string propertyName) {
    
            propertyName = default(string);
    
            var propertyExpression = expression.Body as MemberExpression;
            if (propertyExpression == null)
                return false;
    
            propertyName = propertyExpression.Member.Name;
            return true;
        }
    
        public override string ToString() {
            return _objType.Name + "{" + _innerSb.ToString() + "}";
        }
    }
    

    // from within some class with an Id and Name property
    public override string ToString() {
        return new ToStringBuilder<SomeClass>(this)
            .Append(x => x.Id)
            .Append(x => x.Name)
            .ToString();
    }
    

    瞧,你所追求的行为:

    class Thing {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public override string ToString() {
            return new ToStringBuilder<Thing>(this)
                .Append(t => t.Id)
                .Append(t => t.Name)
                .ToString()
        }
    }
    
    void Main() {
        var t = new Thing { Id = 10, Name = "Bob" };
        Console.WriteLine(t.ToString());
    }
    

    输出:

    东西{Id:10,名字:“Bob”}

        2
  •  4
  •   chillitom Cee McSharpface    14 年前

    最初的问题是关于C#3.5,但从那以后我升级到了C#4。

    ToStringBuilder

        3
  •  3
  •   Mike Two    15 年前

    它可能不是你想要的,因为它不是免费的,但是 Resharper

        4
  •  1
  •   Faizan S.    15 年前

    使用.NET的 StringBuilder .

    例如:

    public StringBuilder ToStringBuilder<T>(T type) where T : IYourInterface
    {
    StringBuilder sb = new StringBuilder();
    sb.append(type.key);
    // more appends
    
    return sb;
    }
    

    提供了一种 generic 就在这里。 您将能够使用 System.Reflection

    干杯

        5
  •  1
  •   mxmissile    15 年前

    查看此项目。。。

    http://commonsdotnet.codeplex.com/

        6
  •  1
  •   drewburlingame    11 年前

    ObjectPrinter 将为您提供许多可定制的功能。文档仍然有点粗糙,但我们已经在生产中使用了多年,并取得了很好的效果。

        7
  •  0
  •   JMarsch    15 年前

    我想你已经掌握了使用表达式的方法。前几天晚上我读了这篇文章: Getting Information About Objects, Types, and Members with Expression Trees

        8
  •  0
  •   Seth Petry-Johnson    15 年前

    下面是另一个使用匿名委托的[未经测试/未编译/可能有错误]想法:

    public override string ToString() {
        return this.ToString(x => {
            x.Append(t => t.Id);
            x.Append(t => t.Name);
        });
    }
    

    ToString() 重载将作为扩展方法编写,因此您将获得对源对象的引用,并接受 Action<T> 其中[T]是源对象的类型。然后,ToString()方法将新建一个字符串生成器或某种内部对象,执行从调用者传入的匿名方法,然后将结果包装在任何必要的开始/结束文本中。

    说清楚点,我还没有 这我只是觉得它比原来问题中基于lambda的例子灵活一点。