ValueType
参照型です。本音。の場合は構造体のみですT
。ValueType
ボックスにしないようにするには、すべてをに置き換える必要がありT
ます。ただし、組み込みのキャスト from T
to int
... はないため、できません。ボックスにする必要があります。さらに、すべての列挙型がint
ベースであるとは限りません (たとえば、 box-as-enum、unbox-as-int は a に対して失敗しenum Foo : ushort
ます)。
C# 4.0 では、dynamic
これを行うための生意気な方法かもしれません。
public static T Include<T>(this T type, T value) where T : struct
{
return ((dynamic)type) | value;
}
それ以外の場合は、いくつかのメタプログラミング (基本的に何を行うかをdynamic
手動で行います):
static void Main()
{
var both = Test.A.Include(Test.B);
}
enum Test : ulong
{
A = 1, B = 2
}
public static T Include<T>(this T type, T value) where T : struct
{
return DynamicCache<T>.or(type, value);
}
static class DynamicCache<T>
{
public static readonly Func<T, T, T> or;
static DynamicCache()
{
if(!typeof(T).IsEnum) throw new InvalidOperationException(typeof(T).Name + " is not an enum");
var dm = new DynamicMethod(typeof(T).Name + "_or", typeof(T), new Type[] { typeof(T), typeof(T) }, typeof(T),true);
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Or);
il.Emit(OpCodes.Ret);
or = (Func<T, T, T>)dm.CreateDelegate(typeof(Func<T, T, T>));
}
}