c# - 为什么 Enum 的 HasFlag 方法需要装箱?

标签 c# .net enums boxing

我正在阅读“C# via CLR”,在第 380 页上,有一条说明如下:

Note The Enum class defines a HasFlag method defined as follows

public Boolean HasFlag(Enum flag);

Using this method, you could rewrite the call to Console.WriteLine like this:

Console.WriteLine("Is {0} hidden? {1}", file, attributes.HasFlag(FileAttributes.Hidden));

However, I recommend that you avoid the HasFlag method for this reason:

Since it takes a parameter of type Enum, any value you pass to it must be boxed, requiring a memory allocation ."

我无法理解这个加粗的语句——为什么“

any value you pass to it must be boxed

flag参数类型是Enum,是值类型,为什么会有装箱? “您传递给它的任何值都必须装箱”应该意味着装箱发生在您将值类型传递给参数 Enum flag 时,对吧?

最佳答案

值得注意的是,一个通用的 HasFlag<T>(T thing, T flags)这比 Enum.HasFlag 快了大约 30 倍扩展方法可以用大约 30 行代码编写。它甚至可以做成一个扩展方法。不幸的是,在 C# 中不可能限制这种方法只接受枚举类型的东西;因此,即使对于它不适用的类型,Intellisense 也会弹出该方法。我认为如果有人使用 C# 或 vb.net 以外的某种语言来编写扩展方法,则可能只在应该弹出时弹出它,但我对其他语言还不够熟悉,无法尝试这样的事情。

internal static class EnumHelper<T1>
{
    public static Func<T1, T1, bool> TestOverlapProc = initProc;
    public static bool Overlaps(SByte p1, SByte p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(Byte p1, Byte p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(Int16 p1, Int16 p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(UInt16 p1, UInt16 p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(Int32 p1, Int32 p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(UInt32 p1, UInt32 p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(Int64 p1, Int64 p2) { return (p1 & p2) != 0; }
    public static bool Overlaps(UInt64 p1, UInt64 p2) { return (p1 & p2) != 0; }
    public static bool initProc(T1 p1, T1 p2)
    {
        Type typ1 = typeof(T1);
        if (typ1.IsEnum) typ1 = Enum.GetUnderlyingType(typ1);
        Type[] types = { typ1, typ1 };
        var method = typeof(EnumHelper<T1>).GetMethod("Overlaps", types);
        if (method == null) method = typeof(T1).GetMethod("Overlaps", types);
        if (method == null) throw new MissingMethodException("Unknown type of enum");
        TestOverlapProc = (Func<T1, T1, bool>)Delegate.CreateDelegate(typeof(Func<T1, T1, bool>), method);
        return TestOverlapProc(p1, p2);
    }
}
static class EnumHelper
{
    public static bool Overlaps<T>(this T p1, T p2) where T : struct
    {
        return EnumHelper<T>.TestOverlapProc(p1, p2);
    }
}

编辑:以前的版本被破坏了,因为它使用(或至少尝试使用)EnumHelper<T1 <强> , T1 > .

关于c# - 为什么 Enum 的 HasFlag 方法需要装箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11665279/

相关文章:

c# - 创建将两个整数列表合并为元组列表的函数

c# - 在没有自动 setter / getter 的情况下在 C# 中设置列​​表项

c# - asp.net mvc3 应用程序的状态通知系统

c# - 从一个队列中删除存在于另一个队列中的元素

.net - FICTIVE IF 的目的是什么?

c# - .NET C# - 数组中不同数组的数量

c# - 如何在 Windows 中以编程方式获取电源使用情况

c++ - 将 char 绑定(bind)到枚举类型

java - 通过依赖注入(inject)设置 Java Enums 值

generics - 为什么我不能在通用枚举类上调用 .values() ?