c# - quiénes - tilde lleva tilde
C#: conexión entre IFormattable, IFormatProvider e ICustomFormatter, y cuándo usar qué (2)
¿Cuál es la diferencia y conexión entre IFormattable
, IFormatProvider
e ICustomFormatter
y cuándo se usarían? Un ejemplo de implementación simple sería muy bueno también.
Y realmente no me refiero a cuando se usa en el marco .net, sino cuando implementaría yo mismo y en ese caso qué clases implementarían típicamente qué interfaz y cómo hacerlo correctamente.
IFormattable
es un objeto que admite formatos diferentes (denominados / personalizados), por ejemplo, números, etc. Al usar una interfaz, múltiples bloques de código pueden usar el valor y una cadena de formato, y esto es común (por ejemplo) en datos- encuadernación y string.Format
. string.Format
.
Un IFormatProvider
llena algunos vacíos relacionados con el formateo, especialmente i18n. Más comúnmente, se utiliza un CultureInfo
como proveedor, ya sea dando un formato local específico o la cultura invariante.
Hasta donde yo sé, ICustomFormatter
no está relacionado y se relaciona más con la serialización ( BinaryFormatter
). Podría estar equivocado...
Un ejemplo de un objeto IFormattable
:
IFormattable d = 123.45M;
string s1 = d.ToString("c", CultureInfo.CurrentCulture), // local currency
s2 = d.ToString("c", CultureInfo.InvariantCulture); // invariant currency
IFormattable
es un objeto que admite formatos enstring.Format
, es decir,xxx
en{0:xxx}
.string.Format
delegará en el métodoIFormattable.ToString
un objeto si el objeto admite la interfaz.IFormatProvider
es una fuente de información de configuración que los formateadores usan para cosas como la fecha específica de la cultura y el diseño de moneda.Sin embargo, para situaciones como, por ejemplo,
DateTime
, donde la instancia que desea formatear ya implementaIFormattable
pero no controla la implementación (DateTime
se suministra en el BCL, no puede reemplazarlo fácilmente), hay un mecanismo para evitarstring.Format
desde simplemente usandoIFormattable.ToString
. En su lugar, implementaIFormatProvider
, y cuando se leICustomFormatter
una implementación deICustomFormatter
, devuelva uno.string.Format
comprueba el proveedor de unICustomFormatter
antes de que delegue en el objetoIFormattable.Format
, que a su vez probablemente le pida alIFormatProvider
cultural específica comoCultureInfo
.
Aquí hay un programa que muestra qué string.Format
pregunta a IFormatProvider
y cómo va el flujo de control:
using System;
using System.Globalization;
class MyCustomObject : IFormattable
{
public string ToString(string format, IFormatProvider provider)
{
Console.WriteLine("ToString(/"{0}/", provider) called", format);
return "arbitrary value";
}
}
class MyFormatProvider : IFormatProvider
{
public object GetFormat(Type formatType)
{
Console.WriteLine("Asked for {0}", formatType);
return CultureInfo.CurrentCulture.GetFormat(formatType);
}
}
class App
{
static void Main()
{
Console.WriteLine(
string.Format(new MyFormatProvider(), "{0:foobar}",
new MyCustomObject()));
}
}
Imprime esto:
Asked for System.ICustomFormatter
ToString("foobar", provider) called
arbitrary value
Si el proveedor de formato se cambia para devolver un formateador personalizado, se hace cargo de:
class MyFormatProvider : IFormatProvider
{
public object GetFormat(Type formatType)
{
Console.WriteLine("Asked for {0}", formatType);
if (formatType == typeof(ICustomFormatter))
return new MyCustomFormatter();
return CultureInfo.CurrentCulture.GetFormat(formatType);
}
}
class MyCustomFormatter : ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider provider)
{
return string.Format("(format was /"{0}/")", format);
}
}
Cuando se ejecuta:
Asked for System.ICustomFormatter
(format was "foobar")