[解決済み] intを無効なenum値にキャストすると例外が発生しないのはなぜですか?
2022-05-29 20:21:58
質問
このようなenumがあった場合
enum Beer
{
Bud = 10,
Stella = 20,
Unknown
}
をキャストする際に例外が発生しないのはなぜですか?
int
の型にキャストする際に例外が発生しないのはなぜでしょうか?
Beer
?
例えば次のコードは例外をスローせず、コンソールに「50」を出力します。
int i = 50;
var b = (Beer) i;
Console.WriteLine(b.ToString());
私はこれが奇妙に思える...誰か明確にすることができますか?
どのように解決するのですか?
引用元 Enumのパースで混乱する
これは、.NETを作った人たちの判断です。enum は、別の値型 (
int
,
short
,
byte
など)であるため、実際にはこれらの値型に対して有効な任意の値を持つことができます。
個人的にはこのやり方はあまり好きではないので、一連のユーティリティメソッドを作りました。
/// <summary>
/// Utility methods for enum values. This static type will fail to initialize
/// (throwing a <see cref="TypeInitializationException"/>) if
/// you try to provide a value that is not an enum.
/// </summary>
/// <typeparam name="T">An enum type. </typeparam>
public static class EnumUtil<T>
where T : struct, IConvertible // Try to get as much of a static check as we can.
{
// The .NET framework doesn't provide a compile-checked
// way to ensure that a type is an enum, so we have to check when the type
// is statically invoked.
static EnumUtil()
{
// Throw Exception on static initialization if the given type isn't an enum.
Require.That(typeof (T).IsEnum, () => typeof(T).FullName + " is not an enum type.");
}
/// <summary>
/// In the .NET Framework, objects can be cast to enum values which are not
/// defined for their type. This method provides a simple fail-fast check
/// that the enum value is defined, and creates a cast at the same time.
/// Cast the given value as the given enum type.
/// Throw an exception if the value is not defined for the given enum type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumValue"></param>
/// <exception cref="InvalidCastException">
/// If the given value is not a defined value of the enum type.
/// </exception>
/// <returns></returns>
public static T DefinedCast(object enumValue)
{
if (!System.Enum.IsDefined(typeof(T), enumValue))
throw new InvalidCastException(enumValue + " is not a defined value for enum type " +
typeof (T).FullName);
return (T) enumValue;
}
/// <summary>
///
/// </summary>
/// <param name="enumValue"></param>
/// <returns></returns>
public static T Parse(string enumValue)
{
var parsedValue = (T)System.Enum.Parse(typeof (T), enumValue);
//Require that the parsed value is defined
Require.That(parsedValue.IsDefined(),
() => new ArgumentException(string.Format("{0} is not a defined value for enum type {1}",
enumValue, typeof(T).FullName)));
return parsedValue;
}
public static bool IsDefined(T enumValue)
{
return System.Enum.IsDefined(typeof (T), enumValue);
}
}
public static class EnumExtensions
{
public static bool IsDefined<T>(this T enumValue)
where T : struct, IConvertible
{
return EnumUtil<T>.IsDefined(enumValue);
}
}
こうすれば、言える。
if(!sEnum.IsDefined()) throw new Exception(...);
...または
EnumUtil<Stooge>.Parse(s); // throws an exception if s is not a defined value.
編集
上記の説明に加えて、.NET版のEnumはJavaにインスパイアされたものよりもCにインスパイアされたパターンに従っていることを認識する必要があります。これによって
ビット フラグの列挙が可能です。
で、バイナリ パターンを使用して、特定の "flag" が enum 値でアクティブであるかどうかを判断することができます。もし、可能な限りのフラグの組み合わせを定義しなければならないとしたら (すなわち
MondayAndTuesday
,
MondayAndWednesdayAndThursday
など)、これらは非常に面倒なことです。ですから、未定義の列挙型の値を使用する能力があると、本当に便利です。この種のトリックを活用しない列挙型のフェールファスト動作が必要な場合、少し余分な作業が必要になります。
関連
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み】統合マネージドパイプラインモードで適用されないASP.NETの設定が検出された
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】aspNetCore 2.2.0 - AspNetCoreModuleV2 エラー
-
[解決済み】インデックスが範囲外でした。コレクションパラメータname:indexのサイズより小さく、非負でなければなりません。
-
[解決済み】パラメータ付きRedirectToAction
-
[解決済み] C#でenumからint値を取得する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】"出力タイプがクラスライブラリのプロジェクトは直接起動できない"
-
[解決済み] 保護レベルによりアクセス不能になりました。
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】Visual Studio: 操作を完了できませんでした。パラメータが正しくありません
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み] 2つのリストを結合する
-
[解決済み】C#のバイナリ・リテラル