C# non-boxing conversion of generic enum to int?

前端 未结 9 1926
庸人自扰
庸人自扰 2020-12-04 07:31

Given a generic parameter TEnum which always will be an enum type, is there any way to cast from TEnum to int without boxing/unboxing?

See this example code. This w

9条回答
  •  借酒劲吻你
    2020-12-04 08:00

    Here is a simplest and fastest way.
    (with a little restriction. :-) )

    public class BitConvert
    {
        [StructLayout(LayoutKind.Explicit)]
        struct EnumUnion32 where T : struct {
            [FieldOffset(0)]
            public T Enum;
    
            [FieldOffset(0)]
            public int Int;
        }
    
        public static int Enum32ToInt(T e) where T : struct {
            var u = default(EnumUnion32);
            u.Enum = e;
            return u.Int;
        }
    
        public static T IntToEnum32(int value) where T : struct {
            var u = default(EnumUnion32);
            u.Int = value;
            return u.Enum;
        }
    }
    

    Restriction:
    This works in Mono. (ex. Unity3D)

    More information about Unity3D:
    ErikE's CastTo class is a really neat way to solve this problem.
    BUT it can't be used as is in Unity3D

    First, it have to be fixed like below.
    (because that the mono compiler can't compile the original code)

    public class CastTo {
        protected static class Cache {
            public static readonly Func Caster = Get();
    
            static Func Get() {
                var p = Expression.Parameter(typeof(TFrom), "from");
                var c = Expression.ConvertChecked(p, typeof(TTo));
                return Expression.Lambda>(c, p).Compile();
            }
        }
    }
    
    public class ValueCastTo : ValueCastTo {
        public static TTo From(TFrom from) {
            return Cache.Caster(from);
        }
    }
    

    Second, ErikE's code can't be used in AOT platform.
    So, my code is the best solution for Mono.

    To commenter 'Kristof':
    I am sorry that I didn't write all the details.

提交回复
热议问题