Определяем Разные Строковые Представления Объекта
Даже если внутренние данные одинаковы, иногда их можно представить по-разному. Взять структуру 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/