Quelle est la différence et la connexion entre IFormattable
, IFormatProvider
et ICustomFormatter
et quand seraient-ils utilisés? Un exemple d'implémentation simple serait très bien aussi. Je ne veux pas vraiment dire quand il est utilisé dans le framework .net, mais quand je les implémenterais moi-même et dans ce cas quelles classes implémenteraient typiquement quelle interface et comment le faire correctement.C#: Connexion entre IFormattable, IFormatProvider et ICustomFormatter, et quand utiliser
Répondre
IFormattable
est un objet qui prend en charge les formatsstring.Format
, à savoir lexxx
dans{0:xxx}
.string.Format
va déléguer à la méthodeIFormattable.ToString
si l'objet prend en charge l'interface.IFormatProvider
est une source d'informations de configuration que les formateurs utilisent pour des éléments tels que la mise en page de date et de devise spécifique à la culture.Cependant, pour des situations telles que par ex.
DateTime
, où l'instance que vous souhaitez mettre en œuvre implémente déjàIFormattable
mais vous ne contrôlez pas l'implémentation (DateTime
est fourni dans le BCL, vous ne pouvez pas le remplacer facilement), il existe un mécanisme pour empêcherstring.Format
d'utiliser simplementIFormattable.ToString
. Au lieu de cela, vous implémentezIFormatProvider
et lorsque vous demandez une implémentationICustomFormatter
, renvoyez-en une.string.Format
vérifie le fournisseur pour unICustomFormatter
avant de déléguer àIFormattable.Format
de l'objet, ce qui à son tour demanderait probablement leIFormatProvider
pour des données spécifiques à la culture commeCultureInfo
.
Voici un programme qui montre ce string.Format
demande au IFormatProvider
, et comment le flux de contrôle va:
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()));
}
}
Il imprime ceci:
Asked for System.ICustomFormatter
ToString("foobar", provider) called
arbitrary value
Si le fournisseur de format est modifié pour retourner un formateur personnalisé, il prend en charge:
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);
}
}
Quand course:
Asked for System.ICustomFormatter
(format was "foobar")
IFormattable
est un objet qui prend en charge différents formats (nommés/personnalisés) - par exemple, les nombres, etc. En utilisant une interface, plusieurs blocs de code peuvent utiliser la valeur et une chaîne de format, ce qui est commun) dans la liaison de données et string.Format
.
Un IFormatProvider
comble certaines lacunes en matière de formatage - en particulier i18n. Le plus souvent, un CultureInfo
est utilisé comme fournisseur, soit en donnant un format local spécifique, soit la culture invariante. Pour autant que je sache, ICustomFormatter
est sans rapport, et lie plus en sérialisation (BinaryFormatter
). Je peux me tromper ...
Un exemple d'un objet IFormattable
:
IFormattable d = 123.45M;
string s1 = d.ToString("c", CultureInfo.CurrentCulture), // local currency
s2 = d.ToString("c", CultureInfo.InvariantCulture); // invariant currency
Ceci est une réponse très ancienne, mais pour le bien des enfants: 'ICustomFormatter' est en effet sur le formatage de chaîne, et pour ajouter le support pour les chaînes de format à des types qui ne sont pas' Implémentations IFormattable (ou pour fournir différentes chaînes de format aux objets IFormattable). 'IFormatter' est celui sur la sérialisation. –
- 1. Comment créer et utiliser un IFormatProvider personnalisé pour DateTime?
- 2. quand et pourquoi utiliser C# méthodes accesseurs
- 3. Quand utiliser POJO et Quand utiliser SLSB
- 4. Quand utiliser conserver et quand utiliser copier
- 5. Quand utiliser/proc et quand/dev
- 6. Quand utiliser Page.DataBind() et Control.DataBind()?
- 7. Quand utiliser l'activateur et quand utiliser la méthode d'usine?
- 8. Quand utiliser pushScene et replaceScene?
- 9. Quand utiliser AsyncOperation et AsyncOperationManager
- 10. Pourquoi et quand utiliser LINQ?
- 11. Différences entre PowerShell et C# quand Énumération une collection
- 12. Quand utiliser Propriétés et quand Mapper en Java?
- 13. Quand utiliser un module et quand utiliser une classe
- 14. Hibernate: Quand utiliser getSession() et quand utiliser getCurrentSession()?
- 15. C# Quand dois-je utiliser List et quand devrais-je utiliser arraylist?
- 16. Quand utiliser les classes abstraites et quand utiliser les interfaces en C#
- 17. Connexion entre l'application Facebook et l'application iPhone
- 18. htmlspecialchars() - Comment et quand utiliser et éviter l'utilisation multiple
- 19. Quand utiliser avec (...) {...} en C#?
- 20. Différences C# différant entre VS2008 et IIS6
- 21. Rails et ASP.NET MVC quand utiliser chacun?
- 22. Quelle est la différence entre LinkedList et ArrayList, et quand utiliser lequel?
- 23. Quelle est la différence entre HttpHandler et un contrôle d'utilisateur Web et quand utiliser chacun d'eux?
- 24. Actionscript 3: Quelle est la différence entre l'interface et le résumé et quand les utiliser ..?
- 25. Interop entre C++ et C#
- 26. Différent entre C et C++
- 27. En Objective-C, quand dois-je utiliser les méthodes de classe et quand devrais-je utiliser des méthodes d'instance?
- 28. Connexion entre J2me et SQL Server 2008
- 29. Connexion entre l'iPhone et le serveur
- 30. C# DataGridView.DataSource différence entre utiliser BindingSource et non
Pourquoi renvoyez-vous 'CultureInfo.CurrentCulture.GetFormat' dans' MyFormatProvider.GetFormat'? Et que voulez-vous utiliser le 'IFormatProvider' dans' MyCustomFormatter.Format'? – Svish
Le fournisseur de format par défaut est CultureInfo.CurrentCulture; c'est celui qui est utilisé si vous n'en spécifiez pas un dans l'une des surcharges de 'string.Format'. J'ai déjà expliqué ce que vous utiliseriez pour IFormatProvider - pour fournir des informations de configuration (par exemple demander CultureInfo), pour des choses comme le formatage de date (par exemple pour utiliser CultureInfo.DateTimeFormat). –