45 votes

Comment créer une syntaxe string.format plus conviviale

Je dois créer une très longue chaîne dans un programme et utiliser String.Format. Le problème auquel je suis confronté est de garder une trace de tous les nombres lorsque vous avez plus de 8 à 10 paramètres.

Est-il possible de créer une forme de surcharge acceptant une syntaxe similaire à celle-ci?

 String.Format("You are {age} years old and your last name is {name} ",
{age = "18", name = "Foo"});
 

71voto

Marc Gravell Points 482669

Qu'en est-il de ce qui suit, qui fonctionne aussi bien pour les types anonymes (l'exemple ci-dessous), que pour les types normaux (entités de domaine, etc.):

 static void Main()
{
    string s = Format("You are {age} years old and your last name is {name} ",
        new {age = 18, name = "Foo"});
}
 

en utilisant:

 static readonly Regex rePattern = new Regex(
    @"(\{+)([^\}]+)(\}+)", RegexOptions.Compiled);
static string Format(string pattern, object template)
{
    if (template == null) throw new ArgumentNullException();
    Type type = template.GetType();
    var cache = new Dictionary<string, string>();
    return rePattern.Replace(pattern, match =>
    {
        int lCount = match.Groups[1].Value.Length,
            rCount = match.Groups[3].Value.Length;
        if ((lCount % 2) != (rCount % 2)) throw new InvalidOperationException("Unbalanced braces");
        string lBrace = lCount == 1 ? "" : new string('{', lCount / 2),
            rBrace = rCount == 1 ? "" : new string('}', rCount / 2);

        string key = match.Groups[2].Value, value;
        if(lCount % 2 == 0) {
            value = key;
        } else {
            if (!cache.TryGetValue(key, out value))
            {
                var prop = type.GetProperty(key);
                if (prop == null)
                {
                    throw new ArgumentException("Not found: " + key, "pattern");
                }
                value = Convert.ToString(prop.GetValue(template, null));
                cache.Add(key, value);
            }
        }
        return lBrace + value + rBrace;
    });
}
 

2voto

Preet Sangha Points 39414

pas tout à fait pareil mais en quelque sorte usurpant son identité ... utilisez une méthode d'extension, un dictionnaire et un peu de code:

quelque chose comme ça...

   public static class Extensions {

        public static string FormatX(this string format, params KeyValuePair<string, object> []  values) {
            string res = format;
            foreach (KeyValuePair<string, object> kvp in values) {
                res = res.Replace(string.Format("{0}", kvp.Key), kvp.Value.ToString());
            }
            return res;
        }

    }
 

1voto

Stefan Steinegger Points 37073

implémentation primitive:

 public static class StringUtility
{
  public static string Format(string pattern, IDictionary<string, object> args)
  {
    StringBuilder builder = new StringBuilder(pattern);
    foreach (var arg in args)
    {
      builder.Replace("{" + arg.Key + "}", arg.Value.ToString());
    }
    return builder.ToString();
  }
}
 

Usage:

 StringUtility.Format("You are {age} years old and your last name is {name} ",
  new Dictionary<string, object>() {{"age" = 18, "name" = "Foo"}});
 

Vous pouvez également utiliser une classe anonyme, mais cela est beaucoup plus lent en raison de la réflexion dont vous aurez besoin.

Pour une implémentation réelle, vous devez utiliser une expression régulière pour:

  • permet de s'échapper du {}
  • vérifiez s'il y a des espaces réservés qui n'ont pas été remplacés, ce qui est probablement une erreur de programmation.

1voto

RvdK Points 10793

Qu'en est-il si age / name est une variable dans votre application. Vous auriez donc besoin d’une syntaxe de tri pour le rendre presque unique, comme {age_1}?

Si vous rencontrez des problèmes avec 8-10 paramètres: pourquoi ne pas utiliser

 "You are " + age + " years old and your last name is " + name + "
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X