Существует ли эквивалент ToStringBuilder Java для C#? Что показала бы хорошая версия C#?

В мире Java у нас есть палаты общин Apache ToStringBuilder для помощи с созданием toString () реализации.

Кто-либо знает о достойной бесплатной реализации для C#? Есть ли лучшие альтернативы, о которых я не знаю?

Если бы никакая бесплатная реализация не существует, чем я предполагаю, что этот вопрос становится большим количеством вопроса, "Что сделало бы хороший ToStringBuilder в C# 3?"

Первое, что пришло на ум:

  • Это могло предложить и отражательное и ручное строковое создание ToString.

  • Было бы действительно здорово, если это могло бы использовать Деревья выражений.

Что-то вроде этого..

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

Который возвратился бы:

 "Foo{Id: 1, Name: AName}"
  • Это могло использовать Систему. Отражение. Испустите для предварительной компиляции делегата ToString.

Какие-либо другие идеи?

ОБНОВЛЕНИЕ

Просто для уточнения ToStringBuilder является другим созданием к StringBuilder.. Я ищу что-то сродни функциональности Common Apache ToStringBuilder, это имеет функции, такие как форматирование мультилинии, различные стили и отражение основывают создание ToString.Спасибо.

ОБНОВЛЕНИЕ 2

Я создал свое собственное. Посмотрите здесь.

16
задан Community 23 May 2017 в 12:07
поделиться

6 ответов

EDIT: Хорошо, вы хотите использовать отражение, чтобы не вводить имена свойств. Я думаю, это даст вам то, что вы хотите:

// 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"}

13
ответ дан 30 November 2019 в 21:53
поделиться

Используйте .NET StringBuilder .

Обратите внимание, что вам придется предоставить небольшой шаблон самостоятельно.

Например:

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

return sb;
}

Здесь предоставлен своего рода общий способ. Вы сможете создать собственное изящное решение с пространством имен System.Reflection в .NET

Ура

1
ответ дан 30 November 2019 в 21:53
поделиться

Возможно, это не совсем то, что вам нужно, поскольку оно не бесплатное, но Resharper сделает это. Это фантастический плагин для визуальной студии, который делает гораздо больше, чем просто генерирует ToString. Но это сработает. поместите курсор в свой класс, нажмите alt + insert и выберите элементы форматирования.

3
ответ дан 30 November 2019 в 21:53
поделиться

См. Этот проект ...

http://commonsdotnet.codeplex.com/

1
ответ дан 30 November 2019 в 21:53
поделиться

Я думаю, что вы к чему-то пришли с использованием выражений. Я прочитал эту статью буквально на днях: Получение информации об объектах, типах и членах с помощью деревьев выражений

Я уверен, что вы могли бы объединить эти методы с кодом, который Дэн разместил в этой теме, чтобы получить то, что вы хотите.

0
ответ дан 30 November 2019 в 21:53
поделиться

Я не знаю ни одного существующего проекта, который бы делал то, что вы хотите, но было бы не так сложно реализовать приведенный вами пример с использованием лямбда-выражений. .

Вот еще одна [непроверенная / некомпилированная / возможно ошибочная] идея с использованием анонимных делегатов:

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

Эта перегрузка ToString () будет записана как метод расширения, так что вы получите ссылку на исходный объект, и будет принимать Action , где [T] - тип исходного объекта. Затем метод ToString () создаст новый конструктор строк или какой-либо внутренний объект, выполнит анонимный метод, переданный от вызывающего, а затем заключит результат в любой необходимый открывающий / закрывающий текст.

Для ясности, я на самом деле не пробовал это. Я просто думаю, что он немного более гибкий, чем пример на основе лямбда в исходном вопросе.

0
ответ дан 30 November 2019 в 21:53
поделиться