Как создать собственный пользовательский формат ToString()?

Я хотел бы указать формат формата ToString, но я не уверен в наилучшем способе справиться с этим.

Например, если у меня есть следующие спецификаторы

  • EE = оборудование
  • ED = описание оборудования
  • EI = идентификатор оборудования

так что если я использовал ToString как таковой:

eqp.ToString("EE-EI (ED)")

вывод может быть:

"CAT994-61 (Front end loader)"

Лучше всего будет искать подстроки и выполнять замену токенов?  Есть ли у кого-нибудь пример этого?

В настоящее время я выполняю последовательность string.Replace, которая работает хорошо.

public class Equipment
{
    // (other class code)

    public string ToString(string format)
    {
        string output = format;
        output = output.Replace("EE", _EquipID);
        output = output.Replace("ED", _EquipDescription);
        output = output.Replace("DI", _DepartID);
        return output;
    }

    public override string ToString()
    {
        return _EquipID;
    }
}

Ответы

Ответ 1

Объединяя строковый формат и перегружая ToString, вы можете сделать это:

public override string ToString(string myFormat)
{
    myFormat = myFormat.Replace("EE", "{0}");
    myFormat = myFormat.Replace("EI", "{1}");
    myFormat = myFormat.Replace("ED", "{2}");
    return String.Format(myFormat, this.equipment, this.description, this.id);
}

Вы также можете использовать регулярные выражения, чтобы сделать функции Replace более приятными.


Это можно использовать следующим образом:

oProd.ToString("EE,ED,EI");
oProd.ToString("EE-ED (EI)"); // change order
oProd.ToString("ED-EE,EE,EE (EI)"); // multiple times
oProd.ToString("ED:EI"); // have some missing
etc

String.Format дает вам возможность позиционировать переменные формата любым способом, иметь их несколько раз или отбрасывать некоторые.

Ответ 2

Сначала переопределить ToString()

Затем, если вы хотите, чтобы он был динамическим, вам пришлось бы разобрать строку формата токен за раз и добавить соответствующую строку в вашу строку вывода. Использование спецификаторов с одним буквенным алфавитом сделало бы его немного проще, поскольку вы могли бы разобрать его за один раз. Если это специальный символ, вы выводите соответствующие данные, которые выдает символ.

Итак, что-то вроде этого

public override string ToString(string format)
{
  StringBuilder s = new StringBuilder();

  foreach (char c in format)
  {
    switch (c)
    {
      case 'E':
        s.Append(EquipID);
        break;
      case 'D':
        s.Append(EquipDesc);
        break;
      case 'I':
        s.Append(DepartID);
        break;
      default:
        s.Append(c);
        break;
    }
  }

  return s.ToString();
}

У этого есть относительно небольшое преимущество сделать это за один проход, который более эффективен, чем несколько вызовов замены строк.

Ответ 3

String.Format("{0:foo}", object);

Прервет передачу "foo" до object.ToString(string format);, поэтому имеет смысл разработать аргументы, которые ваш метод ToString(string format) принимает с учетом этого. В вашем примере

String.Format("{0:EI - EE}", object);

приведет к передаче "EI-EE" методу ToString на объекте, так что это может работать, как вы описываете, но может иметь смысл ограничивать формат одним представлением за раз, например, это

String.Format("{0:EI} - {0:EE}", object);

будет способом получить "CAT994-61" в качестве вывода, а ваш метод ToString() может быть проще

public override string ToString(string myFormat)
{
    string str = null;
    switch (myformat.ToLower())
    {
       case "ee": str = this.equipment; break;
       case "ei": str = this.description; break;
       case "ed": str = this.id; break;
       default: str = this.ToString(); break;
    }
    return str;
}

Если вы уменьшите спецификаторы формата до отдельных букв, это будет более согласовано с тем, как другие объекты обрабатывают форматы ToString.

Ответ 4

Используйте String.Format.

String.Format("{0}-{1} ({2})", "CAT994", 61, "Front end loader");

выводит ожидаемый результат.

Ответ 5

Вам просто нужно перегрузить функцию ToString в ваш объект, например

public override string ToString()
{
    /* some code handling here */
    return ""; //your own formated string
}

Ответ 6

Формат звучит как хорошее решение.
Возможно, несколько (несколько) хороших регулярных выражений, чтобы вырезать вашу входную переменную в группы.

Я бы попытался использовать столько существующих форматов, если вы можете:
http://blog.stevex.net/string-formatting-in-csharp/