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
IFormattablees un objeto que admite formatos enstring.Format, es decir,xxxen{0:xxx}.string.Formatdelegará en el métodoIFormattable.ToStringun objeto si el objeto admite la interfaz.IFormatProvideres 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 implementaIFormattablepero no controla la implementación (DateTimese suministra en el BCL, no puede reemplazarlo fácilmente), hay un mecanismo para evitarstring.Formatdesde simplemente usandoIFormattable.ToString. En su lugar, implementaIFormatProvider, y cuando se leICustomFormatteruna implementación deICustomFormatter, devuelva uno.string.Formatcomprueba el proveedor de unICustomFormatterantes de que delegue en el objetoIFormattable.Format, que a su vez probablemente le pida alIFormatProvidercultural 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")