enum への不満
.NET の enum のパフォーマンスに対する記事を目にする機会は多いと思います。(追記あり)
- [enumはenum以外の用途で使うと遅いのは何故か C#+WPFチューニング戦記]
(http://proprogrammer.hatenadiary.jp/entry/2014/08/17/015345) - Enum.IsDefinedのパフォーマンス - 匣の向こう側 - あまりに.NETな
- EnumオブジェクトのToStringメソッドはswitch文の100倍以上遅いので
ILGeneratorで動的にswitch文を生成&コンパイルして高速化する方法 @higty
他にもジェネリクス関係で IEquatable<T>
, IComparable<T>
を実装してないとか、HasFlag
の制約が甘いとか、Enum.GetValues
の typeof
がいちいち面倒臭いなどなど…。
Enums.NET
そんなときふとこんなライブラリを発見しました。その名も Enums.NET !
どんな機能があるかは github のデモ を見ればおおよそわかると思いますが、何点か特徴をあげます。
-
Enums.GetMembers<T>()
で値と名称をまとめて foreach できる。 -
HasAllFlags<T>()
,HasAnyFlags<T>()
,RemoveFlags<T>()
等のフラグ操作。 - キャッシュをもつことによる高速化
引用元
…皆さんお気づきだろうか?
あれ!? Enum ってジェネリクスの制約につかえなくね?(追記あり)
public static void Hoge<T>(this T @this)
where T : Enum // コンパイルエラー
{
}
しかし、実は C# でできないだけで、MSIL 等で記述すれば可能なのです。
C# のジェネリックで Enum/Delegate 制約を使う - 捨てられたブログ
Enums.NET では Fody.ExtraConstraints を使って制約を付加しています。
いつも Fody.PropertyChanged のお世話になっていて MSIL の件も知っていたのに、こんな発想は1ミリも出てこなかった…。世のエンジニアの方々には脱帽するほかありません。
追記1
@mak_in さんより C# 7.3 にて Enum と Delegate が制約に使えることを教えていただきました。
まだリリース前なので、アップデートを待ちましょう。
C# 7.3 の新機能 未確認飛行 C
追記2
.NET Core 2.1 では HasFlag のパフォーマンスが上がるそうです。
Enum.HasFlag(Enum) のパフォーマンスの測定