2010-06-16 3 views
2

Compte tenu de la méthode suivante: (méthode réelle a quelques autres paramètres, mais les plus importants sont ci-dessous ...)Comment puis-je connaître le nombre de remplacements dans une chaîne de formatage?

public string DoSomething(string formatter, params string[] values) 
{ 
    // Do something eventually involving a call to String.Format(formatter, values); 
} 

est-il un moyen de savoir si mon tableau de valeurs a suffisamment d'objets en elle pour couvrir le formateur, de sorte que je peux lancer une exception s'il n'y en a pas (à moins de faire la chaîne.Format, ce n'est pas une option jusqu'à la fin en raison de certaines conversions lambda)?

+1

Eh bien, vous pouvez analyser la chaîne de formatage, mais pouvez-vous élaborer sur pourquoi vous ne pouvez pas simplement appeler chaîne.Format? – Skurmedel

+0

Parce qu'il ne veut pas faire son travail lambda jusqu'à ce qu'il sache qu'il a assez de paramètres ... –

+0

Regardez le code source. S'ils peuvent comprendre combien de jetons il y a, vous devriez aussi. –

Répondre

4

Je ne comprends toujours pas pourquoi vous pensez que vous ne pouvez pas utiliser string.Format pour le tester. Si le passé dans formatter est censé avoir des espaces réservés pour les éléments de valeurs, alors vous devriez être en mesure de le faire:

static void TestFormat(string formatter, params string[] values) 
{ 
    try 
    { 
     string.Format(formatter, values); 
    } 
    catch (FormatException e) 
    { 
     throw new Exception("the format is bad!!", e); 
    } 
} 

Exemple d'utilisation:

 TestFormat("{0}{1}{2}", "a", "b", "c"); // works ok 
     TestFormat("{0}{1}{2}", "a", "b"); // throws exception 
     TestFormat("{0}{1}{2}}0{", "a", "b", "c"); // throws exception 

Essayer de le faire avec une expression régulière va être dur, parce que ce quelque chose comme ceci:

"{0}, {1}, {abc}, {1a4} {5} }{" 

{abc} et {1a4} ne sont pas valables pour string.Format, et vous aussi avoir à déterminer pour chaque nombre valide ({0}, {1}, {5}) que vous avez au moins autant d'arguments. En outre, le }{ entraînera string.Format également échouer.

Je viens d'utiliser l'ancienne approche décrite ci-dessus dans un projet récent et cela a bien fonctionné.

+0

Comment cela répond-il à la question? Je peux penser à plusieurs raisons pour lesquelles vous auriez besoin de savoir combien de jetons doivent être remplis. Vous pouvez les remplir avec des valeurs différentes en fonction du nombre de jetons disponibles. Pensez à la façon dont asp.net mvc webform view-engine utilise des chaînes pour trouver des vues. C'est un usage valide, non? –

+0

Je suppose que je peux utiliser string.Format pour tester les valeurs initialement même si les types d'entrée ne sont pas ce que je vais éventuellement utiliser pour formater la chaîne. Le nombre d'éléments correspond dans les deux cas. Toutes mes excuses pour la question mal écrite. – sdanna

+0

@Estaban Araya - Reportez-vous à l'OP: "Y at-il un moyen de dire si mon tableau de valeurs a assez d'objets pour couvrir le formateur". C'est ce que fait la solution ci-dessus, et j'ai fourni des exemples pour le prouver. Je ne sais pas ce que vous attendez d'autre ici. Évidemment, cela a résolu le problème du PO puisqu'ils l'ont accepté. – dcp

0

Utilisez un regex pour compter le nombre de modèles, mais attention, car

string.Format("{0}{0}", 123) 

est valide.

Vous avez vraiment besoin de fournir plus d'informations pour cette question à répondre ok ...

+0

Et {{}} remplacer par des accolades simples. –

0

Vous pourriez faire un RegEx pour les formatteurs accolade, puis de les comparer à la longueur du tableau de valeurs.

+2

Je ne pense pas que regex soit une solution très robuste.Par exemple, imaginez tous les espaces réservés possibles dans une chaîne de mise en forme, comme '{0: yyyy-MM-dd}' ou des accolades échappées '{{{0} {1}}}' qui provoqueraient un regex et échouer. – Skurmedel

2

Je pense que vous vous inquiétez trop à ce sujet. Si la chaîne de format n'est pas valide, laissez string.Format lever l'exception pour vous. Si vous ne voulez pas qu'un FormatException soit lancé, attrapez-le et lancez l'exception que vous voulez.

Il ne doit pas vraiment être un problème que vous avez déjà fait une certaine transformation (par exemple. L'évaluation des conversions lambda) parce que c'est après tout une circonstance exceptionnelle (avec peut-être l'exception que les lambdas sont très coûteux, en Dans ce cas, faites d'abord le test string.Format sans traiter les arguments pour vérifier qu'il est valide, puis répétez-le lorsque vous en aurez besoin plus tard après le traitement).

+0

C'est vrai, c'est un cas exceptionnel. Si c'était le code que j'écrivais pour moi-même, j'utiliserais probablement cette approche parce que bien ... Je sais comment ça fonctionne parce que je l'ai écrit. Une des entrées supplémentaires est une liste et j'écris cette méthode avec d'autres développeurs en tête, donc être capable de revenir rapidement serait la solution idéale dans ce cas car je ne sais pas comment la méthode sera utilisée. – sdanna

Questions connexes