在Java世界中,我们使用Apache Commons的ToStringBuilder来帮助创建toString()实现。

有人知道C#的体面的免费实现吗?有我不知道的更好的选择吗?

如果没有免费的实现,我猜这个问题将变成的问题:“在C#3中,什么能成为一个好的ToStringBuilder?”

从我的头顶上:

  • 它可以提供反射和手动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委托(delegate)。

  • 还有其他想法吗?

    更新

    只是为了阐明ToStringBuilder与StringBuilder是另一种生物。.我正在寻找类似于Apache Common ToStringBuilder的功能,它具有多行格式,不同样式和反射基础ToString创建等功能。谢谢。

    更新2

    我已经建立了自己的。参见here

    最佳答案

    编辑:好的,您想使用反射,因此不必键入属性名称。我认为这将为您带来帮助:

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

    输出:

    10-02 04:27