列挙型の値をタイプ別にドロップダウン リストに追加する C# コードがあります。列挙型である T1 で呼び出す必要がありますが、列挙型はこれが不可能な特殊なケースであるため、これを型制約として指定することはできません。これは内部でのみ使用され、文書化されているため、大きな懸念事項ではありません。
Description は System.Enum の拡張機能であり、列挙型の値の DescriptionAttribute の値、または値が指定されていない場合は ToString の値を返します。
このため、LINQ ステートメントの Cast 部分で System.Enum にキャストする必要があり、T1 にキャストしないと、Description 拡張機能を使用できません。
public static void AddEnum<T1>(this System.Web.UI.WebControls.DropDownList me)
{
Type t = Enum.GetUnderlyingType(typeof(T1));
var l = Enum.GetValues(typeof(T1))
.Cast<System.Enum>()
.Select(x => new ListItem(x.Description(),
Convert.ChangeType(x, t)
.ToString()));
me.Items.AddRange(l.ToArray());
}
これは問題なく、Visual Studio 2008 の Web 開発サーバーでは機能しますが、IIS 6 で実行するとキャスト例外で失敗します。ASP ページを設定するための型パラメーターとして変更されず、ハードコードされた列挙型を使用して実行されます。
System.InvalidCastException: '%namespace.class+nameofenum%' から 'System.Enum' へのキャストが無効です。System.Convert.DefaultToType (IConvertible 値、型 targetType、IFormatProvider プロバイダー) で System.Convert.ChangeType (オブジェクト値、型 conversionType、IFormatProvider プロバイダー) で System.Linq.Enumerable.d__b0
1.MoveNext() at System.Linq.Enumerable.<SelectIterator>d__d
2.MoveNext() で System.Linq。1..ctor(IEnumerable
AddEnum[T1](DropDownList me) で System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 ソース) でバッファ1 ソース)
(名前空間/クラス名は私によって隠されています)
他のバージョンの IIS でテストすることはできませんが、開発バージョンが運用システムと一致しないのは非常に奇妙に思えます。これがなぜなのか誰か知っていますか?