4

次のスイッチを短く読みやすいコードで記述する方法はありますか?

switch (SomeValue)
{
  case "001": return DoMethod1(); break;
  case "002": return DoMethod2(); break;
  //etc..
}

みたいな感じで考えていました

Dictionary<string, Func<int>> MethodsByValue = new Dictionary<string, Func<int>>()
{
    { "001", DoMethod1 },
    { "002", DoMethod2 },
}

これを呼び出す

return MethodsByValue[SomeValue]();

しかし、これは可能ですか?それとも、私は箱から遠く離れた方法を考えていますか. このようなものは見つかりませんでしたが、可能であればキーワードがわかりません。

編集: Lasse V. Karlsen の要求に答えるには:

これが私のプロジェクトのコードです。いくつかの場所で名前が変更されたため、元の名前は問題ではありません。母国語だからです。

public string GetRecord420(Dictionary<DataClass, object> dictionaryName)
{
  // some code here
}

public string GetRecord421(Dictionary<DataClass, object> dictionaryName)
{
  // some code here
}

//(Temperary) solution with the switch statement in a wrapper:
public string GetRecordByString(string s, Dictionary<DataClass, object> dictionaryName)
{
  switch (s)
  {
    case "320": return GetRecord420(dictionaryName);
    case "321": return GetRecord421(dictionaryName);
    default: return String.Empty;
  }
}

//How I hoped it could be, with a mapping dictionary.
public Dictionary<string, Func<string, Dictionary<DataClass, object>>> MethodByString = 
   new Dictionary<string, Func<string, Dictionary<DataClass, object>>>()
{
  { "320", GetRecord420 },
  { "321", GetRecord421 },
}

DataClass は、一部の列データ (列名、列タイプなど) を格納する Entity クラスです。

ディクショナリの部分を試しましたが、次のエラーが表示されます: メソッド グループから System.Func<...> に変換できません。

() => GetRecord420 に変更すると、次のエラーが表示されます: ブロック内の戻り値の型の一部がデリゲートの戻り値の型に暗黙的に変換できないため、ラムダをデリゲート型 System.Func<...> に変換できません。

4

4 に答える 4

1

メソッド定義にエラーがあるはずです。

class Program
{
    static void Main()
    {
       var methods = new Dictionary<string, Func<int>>
           {
               { "001", DoMethod1 }
           };
    }

    static int DoMethod1()
    {
        return 1;
    }
}

完全に有効な構文です。

しかし、これはswitch1 つの説得力のある 1 つの主観的な理由よりも優れているわけではありません。

定数またはリテラルと比較する場合は、switch を使用する必要があります。これにより、コンパイラは追加の分析なしでコンパイル時の最適化を実行できます。

もっと主観的に言えば、ディクショナリ/ルックアップ アプローチは短くはなく、読みにくいと思います。ただし、比較条件が実行時に変化する状況では役立ちます。

switch因子を関数に書き換えるのを避けたい場合。言う、

Func<int> MethodsByValue(string value)
{
    switch(value)
    {
        case "001":
            return DoMethod1;

        default:
            return DoMethod2;
    }
}

どちらにしても、

メソッドを列挙するために任意の文字列を使用するのではなく、enum? そうすれば、パフォーマンスと可読性の利点がさらに得られます。

于 2013-06-17T10:10:42.897 に答える
0

一般に、 switchの適切な代替手段はState Design Patternを使用することであり、他の適切な代替手段はStrategy Patternです。これにより、コードがより拡張可能になり、よりオブジェクト指向のアプローチになります。

于 2013-06-17T10:28:02.833 に答える
0

冗長なbreaks を削除するだけで、持っているものを短縮できます。2 つのケースで同じメソッドを呼び出す必要がある場合は、失敗する可能性があります。

switch (SomeValue) {
  case "001": return DoMethod1();
  case "002": return DoMethod2();
  case "003": 
  case "004": return DoMethod34();
  //etc..
}

あなたの疑似提案、およびそれを支持する他の回答については、これがどのように短く、またはより簡潔であるかわかりません。ただし、使用法では、コードを削減し、次のように明確にすることができます。

Func<int> GetMethod(string key) {
  return MethodsByValue[key];
}
Func<int> method = GetMethod("001");
method();
于 2013-06-17T10:23:33.113 に答える