有没有一个等同于Java的ToStringBuilder for C#?一个好的C#版本会有什么功能?

2022-09-03 01:31:39

在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 委托。

还有其他想法吗?

更新

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

更新 2

我已经建立了自己的。请参阅此处


答案 1

编辑:好的,你想使用反射,这样你就不必键入属性名称。我认为这会让你得到你所追求的:

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

输出:

Thing{Id: 10, Name: “Bob”}


答案 2

最初的问题涉及 C# 3.5,但从那时起,我已升级到 C# 4。

我想我会在这里分享我的新版本,以防它对其他人有益。它具有此线程中提到的所有功能,并在运行时编译为快速的Stringify方法。

在这里获取:ToStringBuilder