TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.76K subscribers
Post #2256 2.42K
День 1866. #ЗаметкиНаПолях
Определяем Разные Строковые Представления Объекта

Даже если внутренние данные одинаковы, иногда их можно представить по-разному. Взять структуру DateTime. Используя разные модификаторы, вы можете представлять одну и ту же дату в разных форматах.
var dt = new DateTime(2024, 1, 1, 8, 53, 14);
dt.ToString("yyyy-MM-dddd"); //2024-01-Monday
dt.ToString("Y"); //January 2024

Одна дата, но написана по-разному. Также можно предоставить культуру:
var it = new CultureInfo("it-IT");
dt.ToString("yyyy-MM-dddd", it); //2024-01-lunedì


Интерфейс IFormattable позволяет определить такое поведение в наших классах, переопределив метод ToString(). Например:
public class Person : IFormattable
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }

public string ToString(
string? format,
IFormatProvider? fp)
{
// Здесь определяем логику форматирования
}
}

Теперь мы можем определить различные форматы. Согласно принципу близости данных (хранить данные рядом с местом их использования), добавим в Person вложенный класс с доступными форматами:
public class Person : IFormattable
{
…
public static class Formats
{
public const string FirstAndLastName = "FL";
public const string Mini = "Mini";
public const string Full = "Full";
}
}

Наконец, реализуем ToString() с нашими форматами и случаем, когда формат не распознается:
public string ToString(
string? format,
IFormatProvider? fp)
{
switch (format)
{
case Formats.FirstAndLastName:
return $"{FirstName} {LastName}";
case Formats.Full:
{
FormattableString fs =
$"{FirstName} {LastName} ({BirthDate:D})";
return fs.ToString(fp);
}
case Formats.Mini:
return $"{FirstName[0]}.{LastName[0]}";
default:
return this.ToString();
}
}

Заметьте, что в случае Formats.Full мы используем FormattableString, чтобы применить параметр IFormatProvider к конечному результату.

Тестируем
var p = new Person
{
FirstName = "Albert",
LastName = "Einstein",
BirthDate = new DateTime(1879, 3, 14)
};

p.ToString(Person.Formats.FirstAndLastName, it);
//Albert Einstein
p.ToString(Person.Formats.Full, it);
//Albert Einstein (venerdì 14 marzo 1879)
p.ToString(Person.Formats.Full, null);
//Albert Einstein (Friday, March 14, 1879)
p.ToString("INVALID FORMAT", CultureInfo.InvariantCulture);
//Person
$"I am not {p:Full}";
//I am not Albert Einstein (Friday, March 14, 1879)


Источник: https://www.code4it.dev/csharptips/iformattable-interface/
  • 👍 22
More from @netdeveloperdiary
  1. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  2. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  3. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  4. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  5. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  6. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →