2009-02-18 5 views
4

Y at-il un moyen de String.Format un message sans avoir à spécifier {1}, {2}, etc? Est-il possible d'avoir une forme d'auto-incrément? (Similaire à vieux plaine printf)Puis-je transmettre des paramètres à String.Format sans spécifier de nombres?

+0

Quel est le but de ne pas utiliser les numéros? Peut-être que si nous pouvons suivre la raison pour laquelle vous voulez éviter de les utiliser, nous vous aiderons avec une solution plus utile ... – BenAlabaster

+3

J'ai environ 20 paramètres, et écrire un nombre pour chacun est lourd. J'ai également peur de manquer un numéro ou d'utiliser un numéro deux fois. Et je pense que la maintenabilité sans chiffres peut être plus facile. –

+0

Compréhensible je suppose ... Je trouve toujours laborieux si je veux encore incorporer des cordes formatées dans d'autres chaînes encore à être formatées ... et ensuite ajouter les params à la fin du processus qui a aussi les mêmes inconvénients. – BenAlabaster

Répondre

2

Peur pas - où mettrait-il les objets dans la chaîne? En utilisant printf, vous devez toujours placer des spécificateurs quelque part.

+1

Oui, cela ne me dérange pas d'utiliser des spécificateurs, mais je ne veux pas coder les index. –

+0

@Hosam - est-ce dans le but d'intégrer d'autres chaînes de formatage dans des chaînes de formatage, puis en ajoutant tous les paramètres à un stade ultérieur? – BenAlabaster

+0

@balabaster: non, c'est un appel à 'String.Format' pour insérer quelques variables. –

5

Vous pouvez utiliser une solution named string formatting, ce qui peut résoudre vos problèmes.

+0

Merci. C'est bon à savoir à ce sujet. –

0

On pourrait toujours utiliser (non testé), mais je pense qu'il est plus complexe:

public static string Format(char splitChar, string format, 
          params object[] args) 
{ 
    string splitStr = splitChar.ToString(); 
    StringBuilder str = new StringBuilder(format + args.Length * 2); 
    for (int i = 0; i < str.Length; ++i) 
    { 
     if (str[i] == splitChar) 
     { 
      string index = "{" + i + "}"; 
      str.Replace(splitStr, index, i, 1); 
      i += index.Length - 1; 
     } 
    } 

    return String.Format(str.ToString(), args); 
} 
0

je suis venu avec cela, encore une fois, il est un peu encombrant mais cela fonctionne bien pour ce que je devais faire qui était de passer un nombre variable ou des arguments à ma propre fonction de la même manière que j'utiliserais WriteLine. J'espère que ça aide quelqu'un

protected void execute(String sql, params object[] args) 
{ 
    for (int i = 0; i < args.Count(); i++) 
    { 
     sql = sql.Replace(String.Format("{{{0}}}", i), args[i].ToString()); 
    } 
    //... 
} 
+0

pourriez-vous me dire dans quel programme vous l'avez mis en œuvre? Je voudrais faire une injection SQL. Donc, pour être honnête, vous devriez vraiment penser à remplacer ceci en utilisant le ['SqlParameter'] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter.aspx) dans le [' SqlCommand'] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx) – Oliver

1

Je pense que le meilleur moyen serait de passer les noms de propriété au lieu de Numbers. utiliser cette méthode:

using System.Text.RegularExpressions; 
using System.ComponentModel; 

public static string StringWithParameter(string format, object args) 
    { 
     Regex r = new Regex(@"\{([A-Za-z0-9_]+)\}"); 

     MatchCollection m = r.Matches(format); 

     var properties = TypeDescriptor.GetProperties(args); 

     foreach (Match item in m) 
     { 
      try 
      { 
       string propertyName = item.Groups[1].Value; 
       format = format.Replace(item.Value, properties[propertyName].GetValue(args).ToString()); 
      } 
      catch 
      { 
       throw new FormatException("The string format is not valid"); 
      } 
     } 

     return format; 
    } 

Imaginez que vous avez une classe d'étudiant avec des propriétés telles que: Nom, LastName, BirthDateYear et de l'utiliser comme:

Student S = new Student("Peter", "Griffin", 1960); 
string str = StringWithParameter("{Name} {LastName} Born in {BithDate} Passed 4th grade", S); 

et vous obtiendrez: Peter Griffin né en 1960 a passé la 4ème année.

0

Si quelqu'un est intéressé, j'ai modifié la solution de Ashkan pour pouvoir l'exécuter sous WinRT:

/// <summary> 
/// Formats the log entry. 
/// /// Taken from: 
/// http://stackoverflow.com/questions/561125/can-i-pass-parameters-to-string-format-without-specifying-numbers 
/// and adapted to WINRT 
/// </summary> 
/// <param name="format">The format.</param> 
/// <param name="args">The arguments.</param> 
/// <returns></returns> 
/// <exception cref="System.FormatException">The string format is not valid</exception> 
public static string FormatLogEntry(string format, object args) 
{ 
    Regex r = new Regex(@"\{([A-Za-z0-9_]+)\}"); 

    MatchCollection m = r.Matches(format); 

    var properties = args.GetType().GetTypeInfo().DeclaredProperties; 

    foreach (Match item in m) 
    { 
     try 
     { 
      string propertyName = item.Groups[1].Value; 
      format = format.Replace(item.Value, properties.Where(p=>p.Name.Equals(propertyName)) 
       .FirstOrDefault().GetValue(args).ToString()); 
     } 
     catch 
     { 
      throw new FormatException("The string format is not valid"); 
     } 
    } 

    return format; 
} 
Questions connexes