0

私は列挙型に基づく方法を持っています、そして最初に明確にするために私たちはこの状況を持っています:

public void MyMetohd(Somestatus status)
{
if(status == Somestatus.Enum1)
{
DoA();
DoB();
DoC();
DoD();
DoE();
}
if(status == Somestatus.Enum2)
{
DoA();
DoB();
DoC();
DoD();
}

if(status == Somestatus.Enum3)
{
DoA();
DoB();
DoC();
}

if(status == Somestatus.Enum4)
{
DoA();
DoB();
}

if(status == Somestatus.Enum5)
{
DoA();
}
}

この種のコードをどのように最適化しますか(私のものではありません)?

4

10 に答える 10

5

の各メンバーの値を設定すると、比較を使用できますenum

enum Somestatus : int
{
    Enum1 = 1,
    Enum2 = 2,
    ...
}

次に、比較を使用してコードを実行します。あなたはいつもそうするのでDoA()、それから始めましょう。

if(status <= Somestatus.Enum5)
    DoA();

if(status <= Somestatus.Enum4)
    DoB();

if(status <= Somestatus.Enum4)
    DoC();
...

そのように続けてください。このようにして、値が。のときにすべての関数が呼び出されますEnum1

于 2011-01-02T17:28:29.857 に答える
5

最適化とは、「DRYer にする」という意味だと思います。

読みやすいコード (わずかに繰り返しがありますが) と、できるだけ繰り返さないコードとのバランスを取る必要があります。

これを入力するだけで汚い気分になりますが、必要なのがDRYでLOCが少ない場合は、それでうまくいくと思います。

switch (status)
            {
                case Somestatus.Enum1:
                    DoE();
                    goto SomeStatus.Enum2;
                case Somestatus.Enum2:
                    DoD();
                    goto SomeStatus.Enum3;
                case Somestatus.Enum3:
                    DoC();
                    goto SomeStatus.Enum4;
                case Somestatus.Enum4:
                    DoB();
                    goto SomeStatus.Enum5;
                case Somestatus.Enum5:
                    DoA();
                    break;
                default:
                    throw new InvalidArgumentException("Unknown Status");
            }
于 2011-01-02T17:45:01.900 に答える
3

Action列挙値とまたはのリストで辞書キーを使用しAction<T>て実行できます。

Dictionary<int,IList<Action>> actionsPerEnumValue;

このディクショナリに列挙値とそれぞれのアクションを入力します。

関数で、値ごとの関数のリストを取得し、各アクションを呼び出します。

foreach(var act in actionsPerEnumValue[status])
{
    act();
}

例については、このSOの回答を参照してください。

于 2011-01-02T17:25:35.523 に答える
0

一見、switchステートメントが最善のアプローチのように見えますが、その中でも多くのコードが繰り返されています。

switch (status)
{
    case Somestatus.Enum1:
        DoA();
        DoB();
        DoC();
        DoD();
        DoE();
        break;
    case Somestatus.Enum2:
        DoA();
        DoB();
        DoC();
        DoD();
        break;
    ...
}

DoAこれは優れていますが、 etcへの呼び出しが繰り返されるため、まだ理想的ではありません。

于 2011-01-02T17:20:18.800 に答える
0

同じ条件で作業しているときにその値が異なる場合は、switch..case...を使用することをお勧めします。複数の条件をテストする場合はIf..elseを使用します。

于 2011-01-02T17:23:03.787 に答える
0

ロジックが単純になる場合は、ロジックを「反転」することもできます(カバーする列挙型の数とさまざまなアクションの数によって異なります)。

if(status == Somestatus.Enum1 || status == Somestatus.Enum2)
 DoA();

if(status == Somestatus.Enum1 || status == Somestatus.Enum4)
 DoB();

...
于 2011-01-02T17:24:59.850 に答える
0

状態パターンを使用する必要があるように聞こえます

于 2011-01-02T17:26:29.010 に答える
0

これを解決するためにパターンを使用することは、他の人が提案したように最良の解決策になります。さらに別のソリューションを提供したかったのです。

ただし、これを行わないことを強くお勧めします。

public void MyMetohd(Somestatus status)
    DoA();
    if (status != SomeStatus.Enum5) {
        DoB();
        if (status != SomeStatus.Enum4) {
            DoC();
            if (status != SomeStatus.Enum3) {
                DoD();
                if (status != SomeStatus.Enum2) {
                    DoE();
                }
            }
        }
    }
}
于 2011-01-02T18:53:30.493 に答える
0

私自身は Brook のソリューションを使用したいと思いますが、別のエレガントで短いソリューションを指摘したいと思います。

public void MyMethod(Somestatus status)
{
    foreach (Action toDo in new Action[] { DoA, DoB, DoC, DoD, DoE }.Take(5 - (int)status))
        toDo();
}

ただし、これは Somestatus が次のように定義されていることを前提としています。

enum Somestatus
{
    Enum1,
    Enum2,
    Enum3,
    Enum4,
    Enum5
}

私はこのソリューションが学術的であり、非常に短いため気に入っていますが、読みやすさや保守性が優れていないことは確かです。

于 2011-01-02T19:30:00.527 に答える
0

編集:

// ANOTHER WAY
public void MyMetohd(Somestatus status)
{
    switch(status)
    {
        case Somestatus.Enum1:
             do_("ABCDE");
             break;
        case Somestatus.Enum2:
             do_("ABCD");
             // and so on...
        }
}

public static void do_(string s)
{
    foreach(char ch in s)
    {
        switch(ch)
        {
            case 'A':
                 doA();
                 break;
            case 'B':
                 doB();
                 break;
            case 'C':
                 doC();
                 break;
            case 'D':
                 doD();
                 break;
            case 'E':
                 doE();
                 break               
        }
    }
}
于 2011-01-02T17:41:28.483 に答える