メソッドにタイプを入力します。演算子「<」はタイプ「タイプ」では使用できません

Aug 24 2020

頻繁に呼び出すものを静的メソッドに移動して、コードをよりクリーンにしようとしていました。元のコードは次のとおりです。

List<ListItem> listItems = Enum
  .GetValues(typeof(TimelineinfoEnums.StateEnum))
  .Cast<TimelineinfoEnums.StateEnum>()
  .Select(x => new ListItem { 
     Text  = x.ToString(), 
     Value = (int)x })
  .ToList();

TimelineinfoEnums.StateEnumは単なるプレースホルダーです。私のメソッドのポイントは、それを呼び出し、値を渡し、使用してTimelineinfoEnums.StateEnumいる他の列挙型を作成できるようにすることです。SOの他の場所を読んだ後、「エンティティタイプはコンパイル時に文字通り不明、または認識可能」であるため、このような場合は文字列入力を使用する必要があることを確認しました。次のコードを試しました。

 public static List<ListItem> GetDropdownList(string @enum)
 {     
     List<ListItem> listItems = Enum
       .GetValues(@enum.GetType())
       .Cast<@enum.GetType()>()
       .Select(
          x => new ListItem { Text = x.ToString(), Value = (int)x }).ToList();            
          return listItems;
        }

しかし、そうしようとすると、2番目@enum.GetType()に次のエラーが発生しました。

演算子「<」は、タイプ「メソッドグループ」および「タイプ」のオペランドには適用できません。

.GetType()ビットを削除しようとしましたが、エラーが発生します

列挙型は変数ですが、型のように使用されます

私はLinqにあまり詳しくないので、何か簡単なことを見逃している可能性があります。助けてくれてありがとう!

編集:次の ListItemようになります:

 public class ListItem
        {
            public int Value { get; set; }
            public string Text { get; set; }
        }

回答

2 Dai Aug 24 2020 at 18:16

ジェネリックスは引き続き使用できますがstruct, Enum、C#7.3で追加された制約を使用してください。

コードを次のように変更します。

public static List<ListItem> GetDropdownList<TEnum>()
    where TEnum : struct, Enum
{     
     return Enum.GetValues( typeof(TEnum) )
        .Cast<TEnum>()
        .Select( e => new ListItem() { Text = e.ToString(), Value = Convert.ToInt32( e ) } );
        .ToList();

    public static IReadOnlyList<ListItem> Items => _items;
}

上記のコードのパフォーマンスは、静的ジェネリッククラスに移動し、結果を静的フィールドに格納することで改善できることに注意してください。これにより、結果がキャッシュされます(ジェネリック型は型ごとに1回存在するため、この計算を実行する必要はありません)一回以上):

public static class EnumListItems<TEnum>
    where TEnum : struct, Enum
{
    private static readonly IReadOnlyList<ListItem> _items = Enum.GetValues( typeof(TEnum) )
        .Cast<TEnum>()
        .Select( e => new ListItem() { Text = e.ToString(), Value = Convert.ToInt32( e ) } );
        .ToList();

    public static IReadOnlyList<ListItem> Items => _items;
}

そのように使用されます:

IReadOnlyList<ListItem> items = EnumListItems<MyEnum>.Items;

可変リストが必要な場合は、以下を使用して.ToList()ください。

List<ListItem> items = EnumListItems<MyEnum>.Items.ToList();
1 CodeCaster Aug 24 2020 at 18:17

エンティティタイプは、コンパイル時に文字通り不明、または認識可能です

あなたは使用する必要がありますように見えCast()行うことのLINQと有意義な何かをするので、Enum.GetValues()の戻り値の型は、LINQのための一般的なコレクションをサポートするように更新されることはなかったです。また、@enum.GetType()常にを返しSystem.Stringます。

抽出したいのは、列挙型メンバーの整数値とテキスト値だけであり、任意の列挙型からそれらを抽出できます。そう:

private static List<ListItem> GetListItems<TEnum>()
{
    var result = new List<ListItem>();
    
    foreach (object e in Enum.GetValues(typeof(TEnum)))
    {
        result.Add(new ListItem 
        { 
            Text = e.ToString(),
            Value = (int)e
        });
    }
               
    return result;
}

C#7.3以降TEnumSystem.Enumを使用する場合は、に制約する必要があります。また、ループの代わりにLinqが必要な場合は、を使用できますEnum.GetValues(typeof(TEnum)).Cast<System.Enum>()

TEnumコンパイル時にわからない場合は、特定のTypeオブジェクトでジェネリックメソッドを呼び出す方法をご覧ください。およびType.GetType(enumName)