2012-01-20 7 views
0

私はシャープCでこのような何かをしたいと思います:非静的/一定値

int i = 0; 
foreach (Item item in _Items) 
{ 
    foreach (Field theField in doc.Form.Fields) 
    { 
     switch (theField.Name) 
     { 
      case "Num" + i++.ToString(): // Number of Packages 
       theField.Value = string.Empty; 
       break; 
     } 
    } 
} 

私は私ができる場合などNum1を、Num2を、名前の20かそこらのフィールドを持っていますこれを1つのステートメント/ブロックですべて実行してください。そうすることをお勧めします。

しかし、コンパイラはcase文を定数値にする必要があると不平を言っています。ケースステートメントで動的変数を使用する方法があるので、コードを繰り返さないようにすることはできますか?

私はこのメソッドの目的は、私が制御できない命名規則で、フィールドをPDFフォームに取り込むことだと言いました。 "Num1"〜 "Num20"のような名前のフィールドが20行あります。これが私のシナリオでは文字列の連結が役立つ理由です。

+0

[C#switch文の制限 - なぜ?]で議論できなかった(議論されていた)理由は何ですか?(http://stackoverflow.com/questions/44905/c-sharp-switch-statement-limitations-why )私は[この回答](http://stackoverflow.com/a/45584/516797)最高のそれを要約すると思います。 –

+0

'foreach'の内側に' i ++ 'を入れたくないのですか? – TrueWill

+0

C#Switch Statement Limitationsの投稿は私の質問に完全に答えます。ありがとうございます! – nocarrier

答えて

9

いいえこれは単に言語の一部です。値が定数でない場合は、if/else ifまたはそれに類する解決策を使用する必要があります。 (あなたが達成しようとしていることの詳細を知っていれば、ソリューションの詳細を伝えることができるかもしれません)。

基本的に、私はこのようなフィールドの命名規則を持っています。実際にはコレクションが必要です。これは作業がかなり簡単です。

+0

最初にオフ - 私はあなたからの答えを受け取ることを光栄に思います。私はDepth Second EditionでC#を購入しましたが、最終的には、真のプロフェッショナルになるために十分な知識を持った平凡な開発者ではないと感じています。素晴らしい本!私は.NETランタイム、C#の相互作用のあなたの明らかな愛を完全に畏敬の念を持ち、あなたの情熱を本当に感謝しています。 /エンド・ガッシング・コメント。ありがとう! – nocarrier

+0

私はちょうどすぐに追加したい - これを読んでいる人のために、私は偉大なC#深さでどのように偉大なストレスを置くことはできません。それ以外には他には何もありません。作者の品質でそれを比較できる唯一の本は、ダグラス・クロックフォードの「JavaScript - The Good Parts」です。 – nocarrier

+0

@Shawn:あなたは非常に親切です:)この答えが実際にあなたの問題を解決するのに実際に役立つことを願って、もちろん... –

0

方法について:

int i = 0; 
foreach (Item item in _Items) 
    doc.Form.Fields.First(f=>f.Name == "Num" + i++.ToString()).Value = string.Empty; 

項目の目的はしかし、あなたのコードであるかわかりません。

+0

一致する要素が見つからなければ 'First'が例外を送出します。 – TrueWill

+0

@ Krizz何かが欠けていない限り、OPの疑似コードがやろうとしていることをします。どうしたの? –

+0

@TrueWillはい、私は彼がフィールドが見つからない場合に何をしたいのか分かりません。私は彼にそれを残していた。 –

1

はいの大文字小文字の値は、コンパイル時に評価できる必要があります。この代わりにどうすればいいですか

0

いいえ、ありません。

どのようにしてスイッチの交換について:

if (theField.Name.StartsWith("Num")) 
    theField.Value = string.Empty; 

またはいくつかの同様のテスト?より効率について

0
var matchingFields = 
    from item in _Items 
    join field in doc.Form.Fields 
     on "Num" + item.PackageCount equals field.Name 
    select field; 

foreach (var field in matchingFields) 
{ 
    field.Value = string.Empty; 
} 

MoreLINQまたは同等の)マッチングフィールドを取得した後、フィールド名にDistinctByを含みます。

0

また、2つ以上の文字列を連結するたびに、コンパイラは各コンポーネント文字列と最後の文字列のメモリ変数を作成すると考えます。これはメモリを消費し、エラー報告のような非常に大きな文字列の場合、パフォーマンス上の問題でさえあり、実行中のプログラムではメモリ内の断片化が発生する可能性があります。おそらくこのケースではそうではありませんが、あなたの通常の開発ルーチンにベストプラクティスを開発することは良いことです。

ので、代わりにこのように書くの:

string.Format("{0}{1}", "Num", i++.ToString()); 

また、あなたは別の定数クラスに「テンキー」のような文字列を置くことを検討する必要があります。

"Num" + i++.ToString() 

は次のように書いて考えてみましょう。コードに文字列定数を指定すると、プログラムの剛性が損なわれ、プログラムが成長するにつれてプログラムの柔軟性が制限される可能性があります。

だから、あなたはあなたのプログラムの冒頭でこのようなものを持っているかもしれません:

using SysConst = MyNamespace.Constants.SystemConstants; 

次に、あなたのコードは次のようになります。

string.Format("{0}{1}", SysConst.Num, i++.ToString()); 

そして、あなたのSystemConstantsクラスでは、あなたが持っているだろう

/// <summary>System Constants</summary> 
public static class SystemConstants 
{ 
    /// <summary>The Num string.</summary> 
    public static readonly string Num = @"Num"; 
} 

このように、「Num」文字列を使用する必要がある場合は、あなたのプログラムでは、 'SysConst.Num'だけを使用することができます。

さらに、「Num」を「Number」に変更すると、顧客の要求ごとに変更する必要がありますあなたのシステムで大きな検索置換はありません。