为什么枚举的HasFlag方法需要拳? [英] Why Enum's HasFlag method need boxing?

查看:189
本文介绍了为什么枚举的HasFlag方法需要拳?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我CLR通过C#和380页上的阅读,还有一张纸条写着以下内容:

I am reading "C# via CLR" and on page 380, there's a note saying the following:

请注意枚举类定义中定义的HasFlag方法如下:

Note The Enum class defines a HasFlag method defined as follows

公共布尔HasFlag(枚举标志);

使用这种方法,你可以重写这样调用Console.WriteLine:

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

Console.WriteLine(是{0}隐藏{1}?,文件,attributes.HasFlag(FileAttributes.Hidden));

不过,我建议你避免HasFlag方法,因为这个原因:

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

由于需要一个   ENUM类型的参数,你传递给它的任何值必须装箱,需要的内存分配

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

我不明白这个粗体说法 - 为什么

I can not understand this bolded statement -- why "

您传递给它的任何值必须装箱

any value you pass to it must be boxed

? 标志parament类型是枚举,这是值类型,为什么在这里仍然有拳击? 这里的你传递给它的任何值必须装箱应该是指当你通过值类型参数枚举标志拳击发生,对吧?

"? flag parament type is Enum, which is value type, why here still got boxing? here "any value you pass to it must be boxed" should mean boxing happens when you pass value type to parameter "Enum flag", right?

推荐答案

<子>在这种情况下,两名拳击来电都需要之前,你甚至进入 HasFlags 方法。一个是解决对价值类型为基本类型的方法调用的方法,另一种是传递值类型为引用类型的参数。你可以看到相同的IL,如果你这样做 VAR类型= 1.GetType(); ,文字 INT 1在的GetType()来电前的装箱。在方法调用的拳似乎只有在方法中的值类型定义本身没有被重载,更可以在这里阅读:<一href="http://stackoverflow.com/questions/436363/does-calling-a-method-on-a-value-type-result-in-boxing-in-net">Does调用值类型结果的方法,在拳击比赛中的.NET?

In this instance, two boxing calls are required before you even get into the HasFlags method. One is for resolving the method call on the value type to the base type method, the other is passing the value type as a reference type parameter. You can see the same in IL if you do var type = 1.GetType();, the literal int 1 is boxed before the GetType() call. The boxing on method call seems to be only when methods are not overridden in the value type definition itself, more can be read here: Does calling a method on a value type result in boxing in .NET?

HasFlags 需要一个枚举 参数,所以拳击将出现在这里。您正在试图通过什么是值类型弄成期待一个参考类型。为了作为参考,拳击发生重present值。

The HasFlags takes an Enum class argument, so the boxing will occur here. You are trying to pass what is a value type into something expecting a reference type. To represent values as references, boxing occurs.

有很多的编译器支持的价值类型及其继承(与枚举 / 值类型)的混淆情况时试图解释它。人们似乎认为,因为枚举值类型是值类型拳击突然不适用的继承链。如果这是真的,同样可以对象表示因为一切都继承了 - 但我们知道这是假的

There is lots of compiler support for value types and their inheritance (with Enum / ValueType) that confuses the situation when trying to explain it. People seem to think that because Enum and ValueType is in the inheritance chain of value types boxing suddenly doesn't apply. If this were true, the same could be said of object as everything inherits that - but as we know this is false.

这不停止重新presenting值类型为引用类型的将收取拳的事实。

This doesn't stop the fact that representing a value type as a reference type will incur boxing.

和我们在IL证明这(寻找 codeS):

And we can prove this in IL (look for the box codes):

class Program
{
    static void Main(string[] args)
    {
        var f = Fruit.Apple;
        var result = f.HasFlag(Fruit.Apple);

        Console.ReadLine();
    }
}

[Flags]
enum Fruit
{
    Apple
}



.method private hidebysig static 
    void Main (
        string[] args
    ) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 28 (0x1c)
    .maxstack 2
    .entrypoint
    .locals init (
        [0] valuetype ConsoleApplication1.Fruit f,
        [1] bool result
    )

    IL_0000: nop
    IL_0001: ldc.i4.0
    IL_0002: stloc.0
    IL_0003: ldloc.0
    IL_0004: box ConsoleApplication1.Fruit
    IL_0009: ldc.i4.0
    IL_000a: box ConsoleApplication1.Fruit
    IL_000f: call instance bool [mscorlib]System.Enum::HasFlag(class [mscorlib]System.Enum)
    IL_0014: stloc.1
    IL_0015: call string [mscorlib]System.Console::ReadLine()
    IL_001a: pop
    IL_001b: ret
} // end of method Program::Main

同样可以看出,当再presenting 的值类型为值类型,这也导致了拳击:

The same can be seen when representing a value type as ValueType, it also results in boxing:

class Program
{
    static void Main(string[] args)
    {
        int i = 1;
        ValueType v = i;

        Console.ReadLine();
    }
}


.method private hidebysig static 
    void Main (
        string[] args
    ) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 17 (0x11)
    .maxstack 1
    .entrypoint
    .locals init (
        [0] int32 i,
        [1] class [mscorlib]System.ValueType v
    )

    IL_0000: nop
    IL_0001: ldc.i4.1
    IL_0002: stloc.0
    IL_0003: ldloc.0
    IL_0004: box [mscorlib]System.Int32
    IL_0009: stloc.1
    IL_000a: call string [mscorlib]System.Console::ReadLine()
    IL_000f: pop
    IL_0010: ret
} // end of method Program::Main

这篇关于为什么枚举的HasFlag方法需要拳?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆