3

私は今日 C# の学習を始めたばかりで、さまざまな列挙型で操作できる汎用メソッドを作成しようとしています。紙の別の質問で見つけたコードをいくつか取得しましたが、コンパイラーは不平を言い続けています。誰か手を貸してくれませんか。これが私がこれまでに持っているものです:

    static void ReadMenuInput<T>(out T menuInput)
    {
        while (true)
        {
            if (enum<T>.TryParse(Console.ReadLine(), out menuInput) && menuInput < sizeof(T))
            {
                break;
            }
            Console.WriteLine("Please enter a valid input.");
        } 
    }

ご協力ありがとうございました!

4

1 に答える 1

7

その特定のコード スニペットにはいくつかの異なる問題があり、そのうちのいくつかは他のものよりも簡単に対処できます。それらのいくつかは単にあなたの経験不足を示しています:

  • enum交換可能ではありEnumません。1 つはクラス名で、もう 1 つは C# キーワードです。場合によっては ( stringand などString)、キーワードは単なる型のエイリアスですが、型名でenumはなく、型名を定義するために使用されます。クラス メソッドを呼び出すには、Enum.
  • TryParse<>間違った構文でジェネリック メソッドを呼び出そうとしています。である必要がありますEnum.TryParse<T>
  • 列挙と整数は同じ型ではなく、単純に比較することはできません。ただし、明示的な型キャストを介して相互に変換できます。sizeofを返すため、intそのような型キャストが必要です (ただし、以下を参照してください)。

コードサンプルのより複雑な問題:

  • sizeof(enum)あなたが期待することをまったくしないと思います。列挙型のバイト単位のサイズを返します。これは通常 4 になります。IsDefined特定の整数値が列挙型で定義されているかどうかを知ることができるメソッドが必要になる可能性があります。
  • コンパイラが教えてくれるように、このコンテキストでは null 非許容のジェネリック型のみを使用できます。これを定義する方法は、ジェネリック型where T: structに対する制約です。その名前にもかかわらず、これは型を構造体にすることを強制しないことに注意してください。強制的に値型にするだけです。
  • 列挙型でなければならないという制約をジェネリック型に指定する方法はありません。メソッドに他の値の型を渡すと、実行時に例外がスローされます。このケースを適切に処理するのはあなた次第です。

これは、必要なコード スニペットの動作バージョンです (実際にはコンパイルされますが、実際にはテストしていません)。ただし、元のコードの問題はすべて、エラー メッセージを読んで理解するだけで解決できることを指摘しておきます。これは、C# 開発者として習得すべき最も重要なスキルの 1 つです。

static void ReadMenuInput<T>(out T menuInput) where T : struct
{           
  while (true)
  {
    if (Enum.TryParse<T>(Console.ReadLine(), out menuInput)
     && Enum.IsDefined(typeof(T), menuInput))
    {
      break;
    }

    Console.WriteLine("Please enter a valid input.");
  } 
}
于 2012-06-10T03:20:43.423 に答える