私は私のようなものの列挙を持っています:
public enum Things
{
OneThing,
AnotherThing
}
この列挙型の拡張メソッドを記述したいと思います(同様の Priseの回答 )。ただし、このメソッドは列挙型のインスタンスで機能しますが、ala
Things thing; var list = thing.ToSelectList();
代わりに実際の列挙で動作させたい:
var list = Things.ToSelectList();
ただできる
var list = default(Things).ToSelectList();
しかし、私はその見た目が好きではありません:)
私は次の拡張方法で近づきました:
public static SelectList ToSelectList(this Type type)
{
if (type.IsEnum)
{
var values = from Enum e in Enum.GetValues(type)
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
else
{
return null;
}
}
このように使用されます:
var list = typeof(Things).ToSelectList();
それ以上のことはできますか?
拡張メソッドはインスタンスでのみ機能するため、実行できませんが、適切に選択されたクラス/メソッド名とジェネリックスを使用すると、見栄えのよい結果を生成できます。
_public class SelectList
{
// Normal SelectList properties/methods go here
public static SelectList Of<T>()
{
Type t = typeof(T);
if (t.IsEnum)
{
var values = from Enum e in Enum.GetValues(type)
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
return null;
}
}
_
次に、次のような選択リストを取得できます。
_var list = SelectList.Of<Things>();
_
IMOこれはThings.ToSelectList()
よりもはるかに読みやすくなります。
番号。
あなたができる最善のことは、次のようにそれを静的クラスに置くことです:
public static class ThingsUtils {
public static SelectList ToSelectList() { ... }
}
アーロノートの答えは本当に素晴らしいです。それに基づいて、私は次の実装を行いました。
public class SelectList
{
public static IEnumerable<Enum> Of<T>() where T : struct, IConvertible
{
Type t = typeof(T);
if (t.IsEnum)
{
return Enum.GetValues(t).Cast<Enum>();
}
throw new ArgumentException("<T> must be an enumerated type.");
}
}
私の意見では、ほとんど安全に、Enumsでのみ呼び出すことができるため、少し安全です。もちろん、例外のないバージョンが必要な場合は、スローの代わりに単にnullを返すことができます。
@Aaronaughtは非常に良い答えを持っています。彼の答えを拡張するために、より一般的なものにすることもできます。これはグローバルライブラリにあります...
public static IQueryable GetAllEnumValues<T>()
{
IQueryable retVal = null;
Type targetType = typeof(T);
if(targetType.IsEnum)
{
retVal = Enum.GetValues(targetType).AsQueryable();
}
return retVal;
}
これで、この機能はSelectListクラスから切り離されました。したがって、これをSelectListメソッドで呼び出すことも、他の任意の場所で呼び出すこともできます。
public class SelectList
{
public static SelectList Of<T>
{
IQueryable enumValues = GetAllEnumValues<T>();
var values =
from Enum e in enumValues
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}
}
拡張機能を追加するには、「列挙型」の代わりに「タイプ」を使用します。次に、メソッドから任意のタイプのリストを取得できます。ここでは文字列値を返します:
public static string[] AllDescription(this Type enumType)
{
if (!enumType.IsEnum) return null;
var list = new List<string>();
var values = Enum.GetValues(enumType);
foreach (var item in values)
{
// add any combination of information to list here:
list.Add(string.Format("{0}", item));
//this one gets the values from the [Description] Attribute that I usually use to fill drop downs
//list.Add(((Enum) item).GetDescription());
}
return list.ToArray();
}
後でこの構文を使用して、必要なものを取得できます。
var listOfThings = typeof (Things).AllDescription();
私の意見では、これが最もクリーンな方法です。どうして?
System.Enum
new
を追加するだけです。これは小さなトレードオフです(機能するためにはインスタンスが必要なためです)。null
を渡しておらず、別の型で使用しようとしても文字通りコンパイルされません。使用法:
(new Things()).ToSelectList()
拡張方法:
[Extension()]
public SelectList ToSelectList(System.Enum source)
{
var values = from Enum e in Enum.GetValues(source.GetType)
select new { ID = e, Name = e.ToString() };
return new SelectList(values, "Id", "Name");
}