1

I have done the following code (down) as a new project on VS2022 with .NET7 (and C# 11).

The call at the end to "AllFlagsViaBitwise" give me an error:

Error 1 CS0315 The type 'ConsoleAppTestEnumAll.Program.Options' cannot be used as type parameter 'TSelf' in the generic type or method 'IBitwiseOperators<TSelf, TOther, TResult>'. There is no boxing conversion from 'ConsoleAppTestEnumAll.Program.Options' to 'System.Numerics.IBitwiseOperators<ConsoleAppTestEnumAll.Program.Options, int, ConsoleAppTestEnumAll.Program.Options>'. ConsoleAppTestEnumAll C:\prj\Personnel\ConsoleAppTestEnumAll\ConsoleAppTestEnumAll\Program.cs 10 Active

According to "Petrusion" on its answer to another of my question on StackOverflow question How to generically combine all bits (I mean OR all values) of a [FLAGS] enum, having only valid values (bits) declared in the resulting enum?... The code should works. The code works for him.

The code should compile and work as is but I have CS0315, why?

Note: It is part of a new features that come with C# 11 (.Net 7), as far as what I understand.

using System.Diagnostics;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace ConsoleAppTestEnumAll
{
    internal class Program
    {
        [Flags]
        public enum Options
        {
            Opt1 = 1,
            Opt2 = 2,
            Opt4= 4,    
        }

        public class EnumUtil
        {
            public static T AllFlagsViaBitwise<T>() where T : unmanaged, Enum, IBitwiseOperators<T, T, T>, IEqualityOperators<T, T, bool>
            {
                T result = default;
                foreach (var value in Enum.GetValues<T>())
                {
                    if ((result & value) != default)
                    {
                        throw new ArgumentException(
                            $"{typeof(T).Name} is not a flags enum. Detected at enum value {value}", nameof(T));
                    }
                    result |= value;
                }
                return result;
            }
        }

        static void Main(string[] args)
        {
            Debug.Assert(EnumUtil.AllFlagsViaBitwise<Options>() == 7);
        }
    }
}

Project configuration 1/2

enter image description here

Project configuration 2/2

enter image description here

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Eric Ouellet
  • 10,996
  • 11
  • 84
  • 119
  • 1
    Looks like enums does not implement `IBitwiseOperators & IEqualityOperators` (https://github.com/dotnet/runtime/issues/81664), so the code should not compile. It looks like something important missed in the linked answer. – Serg May 04 '23 at 22:18
  • @Serg Thank you very much, that explain my result. Perhaps Petrusion has already C#12 beta? That would explain why it seems to works on his side. – Eric Ouellet May 05 '23 at 13:50
  • @Serg, I think you have the answer. Would you mine to create a solution for it? Wouldn't be a good idea? – Eric Ouellet May 05 '23 at 14:56
  • I don't think that @Petrusion has it working because he's using a newer language version / beta /etc, because the github issue clearly states that the `IBitwiseOperators & IEqualityOperators` support is not currently implemented for `enums` and this even is not planned for the future due to the performance considerations. I also had a quick look at the enum-related sources on github and didn't find any evidence of such a support for `enums` itself (at the same time there is a lot of code that uses such a support for storage types (long/int/...) of enums). – Serg May 05 '23 at 15:21
  • @Serg, Perhaps Petrusion works for Microsoft??? On the question about Enum, I have chosen my own second answer. But I think I should not let this present question open too long if you have the right answer (which I think is fine). Would you mind to create an answer for it? I do not want to take the credit for your answer. Just repeat your first comment and I will accept it as is. Does it looks Ok to you? – Eric Ouellet May 07 '23 at 00:48

1 Answers1

2

According to the documentation enums does not implement IBitwiseOperators & IEqualityOperators. So, the code should not compile.

Also, according to the GitHub discussion (http://github.com/dotnet/runtime/issues/81664), IBitwiseOperators & IEqualityOperators support is not planned for the future due to the performance considerations. I also had a quick look at the enum-related sources on github and didn't find any evidence of such a support for enums itself even for newer runtime versions (at the same time there is a lot of code that uses such a support for storage types (long/int/...) of enums).

To summarize: It looks like the linked answer missed something important that might allow such code to work.

Conclusion: The code provided should not work in the current and all currently (May 2023) known preview versions of .net.

P.S. BTW, I'm still interested in what we can add to such code to make it work as claimed in the linked answer.

Serg
  • 3,454
  • 2
  • 13
  • 17
  • Performance considerations? The whole `Enum` class is just some syntactic sugar for the _real_ enums. The compiler abstracts it away. They could have done the same for `IBitwiseOperators` & `IEqualityOperators` of that class... – JHBonarius Jul 26 '23 at 08:56