web-dev-qa-db-fra.com

String.Format - comment cela fonctionne et comment implémenter des chaînes de format personnalisées

Avec String.Format(), il est possible de formater par exemple DateTime objets de différentes manières. Chaque fois que je recherche le format souhaité, je dois chercher sur Internet. Je trouve presque toujours un exemple que je peux utiliser. Par exemple:

String.Format("{0:MM/dd/yyyy}", DateTime.Now);          // "09/05/2012"

Mais je n'ai aucune idée de comment cela fonctionne et quelles classes prennent en charge ces chaînes supplémentaires "magiques".

Mes questions sont donc:

  1. Comment String.Format Mappe les informations supplémentaires MM/dd/yyyy À un résultat de chaîne?
  2. Tous les objets Microsoft prennent-ils en charge cette fonctionnalité?
    Est-ce documenté quelque part?
  3. Est-il possible de faire quelque chose comme ça:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())
77
hwcverwe

String.Format Fait correspondre chacun des jetons à l'intérieur de la chaîne ({0} Etc.) à l'objet correspondant: http://msdn.Microsoft.com/en-us/library/system. string.format.aspx

Une chaîne de format est facultativement fournie:

{ index[,alignment][ : formatString] }

Si formatString est fourni, l'objet correspondant doit implémenter IFormattable et spécifiquement la méthode ToString qui accepte formatString et renvoie la chaîne formatée correspondante: - http://msdn.Microsoft.com/en-us/library/system.iformattable.tostring.aspx

Un IFormatProvider peut également être utilisé qui peut être utilisé pour capturer les normes/valeurs par défaut de formatage, etc. Exemples ici et ici .

Donc les réponses à vos questions dans l'ordre:

  1. Il utilise la méthode ToString() de l'interface IFormattable sur l'objet DateTime et transmet la chaîne de format MM/dd/yyyy. C'est cette implémentation qui renvoie la chaîne correcte.

  2. Tout objet qui implémente IFormattable prend en charge cette fonctionnalité. Vous pouvez même écrire le vôtre!

  3. Oui, voir ci-dessus.

84
yamen

D'après ma compréhension, vous auriez besoin d'implémenter IFormattable dans votre classe pour prendre en charge cela. Cela a alors la méthode, ToString qui prend les paramètres que vous passez dans String.Format.

Voici un exemple.

// Define other methods and classes here
public class Sample : IFormattable
{
     public string ToString(string format, IFormatProvider provider)
     {
         return String.Concat("Your custom format was ", format);
     }
}

String.Format("{0:MyCustomFormat}", new Sample())
18
Dean Thomas
  1. Consultez les documents MSDN officiels, il y a une liste complète des chaînes de format DateTime ici: http://msdn.Microsoft.com/en-us/library/az4se3k1.aspx . Il y a en effet pas mal de cordes "magiques".

  2. Pour autant que je sache, tous les types n'ont pas un formatage "intéressant", mais tous les types prennent en charge ToString(). Si vous avez besoin de formater un objet intégré, vous pouvez ajouter une méthode d'extension pour le faire, mais généralement le formatage est fourni à tout endroit où il est nécessaire ( ou pour le dire autrement, je n'ai écrit que des formateurs personnalisés pour mes propres types).

  3. Oui, vous pouvez écrire les vôtres et si vous avez des données qui peuvent être formatées de différentes manières, vous devriez probablement écrire un formateur personnalisé en implémentant IFormattable, voir à nouveau les documents ici: http://msdn.Microsoft.com/ fr-fr/library/system.iformattable.aspx . C'est assez simple, vous vérifiez simplement les chaînes fournies et écrivez vos données en fonction de celles-ci, il n'y a pas de magie dans les coulisses :-)

4
Steve Haigh

Sous les couvertures String.Format fait quelque chose comme suit,

IFormattable formattable = objectToFormat as IFormattable;
if (formattable != null)
{
    formattable.ToString(objectToFormat);
}
else
{
    objectToFormat.ToString();
}

Pour vos questions,

  1. Comment String.Format mappe-t-il les informations supplémentaires MM/jj/aaaa à un résultat de chaîne?

    Comme spécifié ci-dessus, il appelle simplement le IFormattable .ToString (format de chaîne, fournisseur IFormatProvider). Le fournisseur est souvent quelque chose qui vous dit quelle est la culture de votre système. Souvent null parce que les gens ne lui transmettent pas String.Format () comme vous l'avez fait dans votre cas.

  2. Tous les objets Microsoft prennent-ils en charge cette fonctionnalité? Est-ce documenté quelque part?

    Tout ce qui implémente IFormattable le fait.

  3. Est-il possible de faire quelque chose comme ceci: String.Format("{0:MyCustomFormat}, new MyOwnClass())

    Essentiellement, si vous voulez que votre propre objet fasse quelque chose avec le format fourni, vous implémentez IFormattable .

Il y a un grand nombre de classes et d'énumérateurs qui prennent en charge pour s'assurer que les chaînes de format sont largement similaires. Plus ici .

3
M Afifi

Oui, c'est possible - il peut être complètement personnalisé. Regardez ce lien de documentation sur la mise en forme personnalisée de la date et de l'heure.

Si vous avez votre propre objet, c'est à vous de remplacer la méthode ToString() et de produire ce que vous pensez être une représentation appropriée. Une fois que vous faites cela, vous pouvez utiliser String.Format("{0:MyCustomFormat}", new MyOwnClass()) car cela appelle implicitement MyOwnClass.ToString()

0
Maciej

La documentation des dates peut être trouvée ici: http://msdn.Microsoft.com/en-us/library/8kb3ddd4.aspx

Cela devrait vous dire exactement ce que signifient tous les caractères de formatage de la date comme MM.

Si vous souhaitez modifier le mode de sortie d'une chaîne pour une classe personnalisée, vous pouvez remplacer la méthode ToString, comme ceci:

public class User
{
     public string Name { get; set; }
     public int Age { get; set; }

     public override string ToString()
     {
         return this.Name + " is " + this.Age + " years old.";
     }
}

et ensuite vous pouvez faire quelque chose comme myUser.ToString() et obtenir la sortie que vous avez spécifiée.

Et pour répondre à votre troisième question: ce n'est pas possible avec cette syntaxe, mais vous pouvez fournir des instances de IFormatProvider et ICustomFormatter pour un type que vous n'avez pas créé, ou implémenter IFormattable à l'intérieur de votre type (bien que cela étend essentiellement ToString).

0
phg