2
    /// <summary>
    /// Specifies flags for the attributes of a method implementation.
    /// </summary>
    [ComVisible(true)]
    [__DynamicallyInvokable]
    [Serializable]
    public enum MethodImplAttributes
    {
      [__DynamicallyInvokable] IL = 0,
      [__DynamicallyInvokable] Managed = 0,
      [__DynamicallyInvokable] Native = 1,
      [__DynamicallyInvokable] OPTIL = 2,
      [__DynamicallyInvokable] CodeTypeMask = 3,
      [__DynamicallyInvokable] Runtime = 3,
      [__DynamicallyInvokable] ManagedMask = 4,
      [__DynamicallyInvokable] Unmanaged = 4,
      [__DynamicallyInvokable] NoInlining = 8,
      [__DynamicallyInvokable] ForwardRef = 16,
      [__DynamicallyInvokable] Synchronized = 32,
      [__DynamicallyInvokable] NoOptimization = 64,
      [__DynamicallyInvokable] PreserveSig = 128,
      [ComVisible(false), __DynamicallyInvokable] AggressiveInlining = 256,
      [__DynamicallyInvokable] InternalCall = 4096,
      MaxMethodImplVal = 65535,
    }

Why is this enum not marked with the FlagsAttribute? It is used like bitfields in all examples you can find on MSDN and most of the guidelines for the attribute on MSDN match this definition.

MethodBuilder.SetImplementationFlags() even implies that it is used like an enum marked with [Flags] aside from the MSDN example code.

bitm0de
  • 45
  • 1
  • 7
  • This enum contravenes all best practices flags enums should adhere to: multiple tags with the same name, values that are combinations of flags (`CodeTypeMask`), values that aren't a flag at all (`MaxMethodImplVal`), a zero value that isn't named `None`. Interestingly, it *was* marked with `FlagsAttribute` in [.NET 1.0](https://msdn.microsoft.com/en-us/library/system.reflection.methodimplattributes(v=vs.71).aspx). The attribute was removed in .NET 2.0, probably to avoid issues with the members that aren't actually flags (but that's speculation as I don't work at Microsoft). – Jeroen Mostert Aug 02 '16 at 09:35
  • Actually, I think it's okay to use flags that are combinations. [The guideline on MSDN says you should define constants for commonly used combinations of flags.](https://msdn.microsoft.com/en-us/library/system.flagsattribute(v=vs.110).aspx). I would agree with everything else you've mentioned though. Although, I wasn't even aware that it was marked with the `FlagsAttribute` in .NET 1.0, that is interesting. I wonder why it was removed or where `MaxMethodImplVal` is even used. If there is a reason it might take a lot of digging to find out why it was removed unless someone else has an idea. – bitm0de Aug 02 '16 at 22:15
  • You're right, the problem with `CodeTypeMask` is not that it's a combination of flags per se, but that it's a mask (as the name implies). Even if this mask were common, it should still not be used as a value in the enum itself. `Runtime` seems to be the tag that represents `Native | OPTIL`. – Jeroen Mostert Aug 03 '16 at 06:22

1 Answers1

0

You can always use bit operations on these enums, even they are not marked with FlagsAttribute. In fact FlagsAttribute is only used in the .ToString method, making the output string more pretty.

enum DataFlag
{
    Private = 1,
    Important = 2,
    Persistant = 4
}

var flag = DataFlag.Private | DataFlag.Persistant;
var test = flag.HasFlag(DataFlag.Private); //True with/without FlagAttribute
var stringResult = flag.ToString();   // with FlagAttribute: Private, Persistant 
                                      // without :   5

And by the way, this enum has MethodImplAttributes.IL = 0, which will not appear in the .ToString output even you have FlagsAttribute, and a few fields have the same value, which probably causes unexpected behavior string result. Generally speaking, it's correct and good practice not marking this attribute with FlagsAttribute.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • It does not show `MethodImplAttributes.IL`, but it will show `MethodImplAttributes.Managed` in the output with the `FlagsAttribute`. I notice that the output name for fields with the same value always _seems_ to be the last field for a `.ToString()` call from my tests. I didn't look closely enough to think about the duplicates however. Good point. However I also read about an interop issue with VB.NET: http://stackoverflow.com/a/5903350/1572874 and this attribute appears to also affect the Parse() and Format() methods in addition to ToString(). – bitm0de Aug 01 '16 at 23:27
  • Also - you don't have access to the `HasFlag()` method as far as I know without this attribute: https://msdn.microsoft.com/en-us/library/system.enum.hasflag.aspx Personally I would care less about outputting the names of my enums for these features, because it seems like a very small price to pay. – bitm0de Aug 01 '16 at 23:35
  • @bitm0de We can call `.HasFlag` without `FlagsAttribute` of course. Why not try it yourself? – Cheng Chen Aug 02 '16 at 01:38
  • Because I had read somewhere that it was required, but the MSDN documentation says it's not meant to be used on Enum's without the FlagsAttribute so it definitely does not seem like a proper option: https://msdn.microsoft.com/en-us/library/system.enum.hasflag.aspx `The HasFlag method is designed to be used with enumeration types that are marked with the FlagsAttribute attribute and can be used to determine whether multiple bit fields are set. For enumeration types that are not marked with the FlagsAttribute attribute, call either the Equals method or the CompareTo method.` – bitm0de Aug 02 '16 at 07:24