2016-11-30 7 views
0

C#でコードジェネレータを作成しています。しかし、私はイニシャライザのリストの印刷に問題があります。私は、コードジェネレータを工夫した例に落としました。私は出力以下のクラスをしたいとしますC#のカスタムWriteLineでString.Formatの初期評価で印刷された中括弧を処理する方法

class Foo 
{ 
    private static int[] m_bar = new[] {256}; 
} 

はここでそれを行うためのプログラム例です:

class Program 
{ 
    private static int m_indentLevel; 

    static void Main(string[] args) 
    { 
    var arrayDimension = 256; 

    WriteLine("class Foo"); 
    WriteLine("{{"); 
    m_indentLevel++; 

    // This works because the format string is passed all the way through to the 
    // Console.WriteLine 
    string initializer = String.Format("new[] {{{0}}}", arrayDimension); 
    WriteLine("private static int[] m_bar = {0};", initializer); 

    // This doesn't work because the format string is evaluated before the Console.WriteLine. 
    var intirim = String.Format("private static int[] m_bar = {0};", initializer); 
    WriteLine(intirim); 

    m_indentLevel--; 
    WriteLine("}}"); 
    } 

    private static void WriteLine(String format, params Object[] arg) 
    { 
    Console.WriteLine("{0}{1}", new String(' ', m_indentLevel * 2), String.Format(format, arg)); 
    } 
} 

このプログラムは、出力にインデントを追跡し、インデントするカスタムWriteLineメソッドを使用しています指定された文字列を適切なレベルに設定します。私のカスタムWriteLineのユーザーが、指定された書式文字列で中括弧(エスケープ)を使用すると、オプションのargを指定せずにWriteLineと呼びます。

private static int[] m_bar = new {256};を書き込む最初の試みは成功し、2番目の例外は例外をスローします。

私のWriteLineを両方の状況で動作させることはできますか?それ、どうやったら出来るの?

+0

おそらく、あなたの 'WriteLine'のオーバーロードを書いてください:' public static void WriteLine(string s){...} '? 'String.Format()'にも同様の理由で多くのオーバーロードがあります。全体のデザインは私にはバグです。 'String.Format()'ですべてをやるのは「素早く簡単」だと思われました。私はその気持ちをよく知っています。ここからそれ以上の成果は得られません。 IMO初めてこのような奇妙なあいまいな絡み合いに遭遇したとき、それを悲惨な警告として受け取ります。あなたの損失をカットし、再設計する。 –

+0

@Ed - あなたが提案する過負荷と条件付きマイクの両方がうまく動作することが示唆されました。 1つは他のものより優先されますか(速いの?) – watkipet

+0

オーバーロードはコンパイル時に解決されるので、私の場合は顕微鏡よりも速くなります。パフォーマンスの違いは気にする必要はありません。私は 'format'引数のために2つの異なるセマンティクスを持っているので私の方が好きです。したがって、同じ名前を持つことになる2つの異なる方法でなければなりません。それは私の見解です。それはあなたの声です。それは、[あなたのデザインの意味を評価してくれた私の有益なアイデアです](http://wheresthejump.com/wp-content/uploads/2015/10/Invasion-of-the-Body-Snatchers-1.jpg) 。 –

答えて

1

あなたのWriteLine()は、2つの異なる意味を持つようにしたい場合はそれを以下のいずれかの追加のパラメータがあり、私自身の好みはそのような場合のために過負荷を書くことであろうかどうかに応じて、formatパラメータについて:

/// <summary> 
/// Indent s and write to Console.Out without String.Format() interpolation 
/// </summary> 
public static void WriteLine(string s) { ... } 

これはConsole.WriteLine()との後に続きます練習;どちらもかなりのオーバーロードがあります。 paramsobjectの過負荷解決は難解で壊れやすいものであるため、これは部分的に必要です。呼び出されて間違った過負荷のために警報に常に出てください。

つまり、your design scares meとなります。それは、私が長年にわたり思いついた "素早く簡単な"デザインを思い出させます。言語機能を使って私の仕事のほとんどを行うことができると思っていました。あなたは、あなたが自由にしたいと思うたくさんのクールなものを手に入れます - しかし、それ以外にもあなたのニーズに合っていないものがたくさんあります。

あなたの車にカヌーを鳴らすためにタコを使用しているようです。確かに、それはすべてのそれらの素敵な長いグリッピーの触手を持っていますが、独自の議題があります。長い目で見れば、ロープは、すべてのことが言われて完了したときに、あなたの部分に必要な労力と工夫が少なくて済みます。

1

intirimは、"private static int[] m_bar = new {256}"を含みます。あなたはString.Formatにそれを渡しています。それはarg[256]を探します。 paramsを渡していないので、明らかに失敗します。私はおそらく同じようWriteLineに条件を追加したい:エドが言うように気をつけて、

string formatted = arg.Length > 0 ? String.Format(format, arg) : format; 
Console.WriteLine("{0}{1}", new String(' ', m_indentLevel * 2), formatted); 

しかし、ウサギの穴が暗くて深いです...

+0

ありがとう。 'arg.length'は' arg.Length'でなければなりません。編集上の最小文字数のために修正できません。 – watkipet

関連する問題