2017-11-15 11 views
0

string.Formatで使用されている書式文字列を自分のアプリケーションのエンドユーザーに編集してもらいたいです。私はテンプレートを編集するユーザーの能力を与えるためにそれをしたいです。ユーザーがマーカーを多すぎると入力すると問題が発生します。string.余分なマーカで例外をスローしない形式の文字列

これは正常に動作します:

var result = string.Format("test {0}, {1}, {2}", 1, 2, 3); 

、これはあまりにも動作します:

var result = string.Format("test {0}, {1}", 1, 2, 3); 

が、これは例外をスロー:

var result = string.Format("test {0}, {1}, {2}", 1, 2); 

にSystem.FormatException:「インデックス(ゼロベース)を0に等しい より大きくなければならず、引数リストのサイズよりも小さい。

私は、マーカーがあるだけ多くのパラメータを追加する必要があるが、エンドユーザーはそのことを知らないこと、または間違いを犯す可能性があることを認識しています。

私の質問は
同様の方法でフォーマット文字列をstring.Formatの方法で使用できますが、例外はありません。

私はtry\catchブロックを使用してフォーマット文字列を返すことができますが、私はそれをしたくありません。

私は、文字列内のマーカーを置き換え、非常に単純な方法で構築してきました:

public static string SafeFormat(string format, params object[] args) 
{ 
    var result = format; 
    for (int i = 0; i < args.Length; i++) 
    { 
     result = result.Replace($"{{{i}}}", args[i].ToString()); 
    } 
    return result; 
} 

が、これは、マーカーの代わりに使用されるデータのフォーマットをサポートしていませんが。

内部でstring.Formatは、私の単純な置き換えより複雑なAppendFormatHelperhttp://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,2c3b4c2e7c43f5a4)を使用しています。

理想的string.Format("test {0}, {1}, {2}", 1, 2)test 1, 2, {2}

+5

をしたい場合は、簡単にユーザーがあなたが提供しようとしているアイテムの数のために不適切な形式の文字列を提供している場合、私はあなたが*すべきだと思う方法に変更することができます*これはエラーとして表示されます。基本的に無駄なデータを作成するよりも早くエラーを報告する方がよい。おそらく、ユーザーは特定の値が出力に存在することを期待しています。単に '{2} 'を含めてもそれらを助けるつもりはありません。 –

+0

@JonSkeet残念ながら、残念ながら私は最初からアプリケーションを構築しているわけではなく、システムはより複雑で、既存のモジュールにエラーがないかテンプレートをチェックする機能を追加すると、非常に古いシステムが特に必要になります。私は最近、異なるアプローチを使用しているテンプレート管理モジュールの新しいバージョンを構築し始めましたが、すぐには準備ができていないので、今は一時的な解決策が必要です。これらのテンプレートは電子メール通知にのみ使用されるため、余分なマーカーがある場合は、電子メールでそのテンプレートに気づくでしょう。 – Misiu

+2

その場合、余分な値を渡すだけではどうですか? 'string.Format(formatString、realValue0、realValue1、" undefined "、" undefined "、" undefined ")'? –

答えて

1

一つの解決策を返す必要がありますが期待されているどのように多くの値をチェックして、単に引数リスト(nullまたはプレースホルダ)に他の人を追加することです。例文字列の拡張子:

public static class StringExtensions 
{ 
    public static string SafeFormat(this string value, params object[] args) 
    { 
     var pattern = @"{(.*?)}"; 
     var matches = Regex.Matches(value, pattern); 
     var matchCount = matches.Count; 
     if (matchCount > args.Length) 
     { 
      var argsExtended = args.ToList(); 
      for (int i = args.Length; i < matchCount; i++) 
      { 
       argsExtended.Add($"{{{i}}}"); //Can add null value to erase them 
      } 
      return string.Format(value, argsExtended.ToArray()); 
     } 
     return string.Format(value, args); 
    } 
} 

あなたは

関連する問題