web-dev-qa-db-ja.com

ifステートメントは機能するのにswitchステートメントは機能しないのはなぜですか

文字列のcharインデックスと this wrapperを使用してEnumを使用してswitchステートメントを作成し、Descriptionから選択した列挙の値を取得しようとしています。文字列を列挙値に保存できます。

これが私のifステートメントです。

if (msgComingFromFoo[1] == Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()))
{
    //foo
}

ここに私のswitchステートメントがあります:

switch (msgComingFromFoo[1])
{
    case Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()):
        break;
}

なぜifではなくswitchステートメントを受け入れるのですか?文字列からインデックスを選択しているので、文字に変換しようとしましたが、残念ながら機能しませんでした。

更新:

これがMessage.Code列挙です

public class Message
{
    public enum Code
    {
        [Description("A")]
        FOO_TRIGGER_SIGNAL
    }
}

ご覧のとおり、0である列挙値ではなく、列挙に割り当てられた説明が必要です。上記のラッパーからMessage.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()を使用すると、0ではなくAが返されます


エラー:

定数値が期待されます

39
AndrewE

ケースに式を含めることはできませんが(C#7より前)、スイッチに含めることができるため、これは機能します。

switch (ConvertToMessageCode(msgComingFromFoo[1]))
{
    case Message.Code.FOO_TRIGGER_SIGNAL:
        break;
}

Message.Code列挙型に必要な変換を行うためにConvertToMessageCodeを記述する必要がある場所。 ConvertToMessageCodeは変換の詳細を単に抽象化します。別のメソッドは必要ないかもしれませんが、switchステートメントのインラインコード(キャストなど)で対応できます。

53
Polyfun

caseステートメントのswitchは、定数値を参照する必要があります。 caseの式を評価することはできません。

27
Code-Apprentice

これは、実際には良い答えではありませんです。これは、以前の答えの詳細としてのみ機能するためです。それを受け入れないでください(また、合理的な答えを支持しないでください)。コメントがこの説明に合わないので、私は答えとしてそれを書いています。


あなたがしようとした:

switch (msgComingFromFoo[1])
{
    case Convert.ToChar(Message.Code.FOO_TRIGGER_SIGNAL.EnumDescriptionToString()):
        break;
}

ケースが一定でないため、これは機能しません。推奨されるように、最善の方法はmsgComingFromFoo[1]文字列を列挙値に変換して、列挙を切り替えて、切り替えの場合に列挙定数を使用することです。

それがどういうわけか不可能な場合は、いつでも文字列定数を切り替えることができます。ただし、これはエラーが発生しやすく、そもそも列挙型を使用する目的に反します。

switch (msgComingFromFoo[1])
{
    case "A":
        break;
}

別のコメント:配列はzero-indexedであることを覚えておいてください。現在、最初の要素ではなく、second要素を切り替えています。最初の要素にはmsgComingFromFoo[0]を使用します。

6
Jochem Kuijpers

@ code-apprenticeの回答に追加します。

ifステートメントが長くなりすぎているか、if else内に複数の条件がある場合。コードをリファクタリングし、ロジックをオブジェクトにカプセル化し、ビジターパターンを使用して実行する作業を制御する方法を確認できます。

何かのようなもの:

public interface IMessageLogic 
{
   void ProcessMessage()
}

public class TriggerSignal : IMessageLogic 
{
   public void ProcessMessage() 
   {
       // Do trigger stuff
   }
}

public class FooMessage : IMessageLogic 
{
   public void ProcessMessage() 
   {
       // Do foo stuff
   }
}

public class MessageHandler
{
    public void HandleMessage(IMessageLogic messageLogic)
    {
        messageLogic.ProcessMessage();
    }
}

public static void Main()
{
    IMessageLogic messageLogic = GetMessage();
    var handler = new MessageHandler();

    handler.HandleMessage(messageLogic);
 }

訪問者パターン

5
Victor Procure