Search code examples
c#.netenumsbitwise-operatorsbitwise-or

C# Understanding why Bitwise OR is used in SSL Protocol assignment


Given the following C# **:

handler.SSLProtocol = SslProtocols.Tls13 | SslProtocols.Tls12;

Where SSLProtocol is the property being assigned. SslProtocols is an Enum. And the pipe | is a bitwise OR.

I know what bitwise OR is, and that it will do the following for example: 101 | 100 = 101.

But, my question is why write the code like this? i.e. why even use bitwise OR?

Why not just set the property like the following for example:

handler.SSLProtocol = SslProtocols.TlsX;

Or whatever the equivalent of SslProtocols.Tls13 | SslProtocols.Tls12 equals using the bitwise or?

(*for the example I'm pretending here that SslProtocols.Tls13 | SslProtocols.Tls1 = SslProtocols.TlsX)

**This line of code was sent to me by a friend and i do not have access to the source to see the Enum or SSLProtocol property definition, but I'm guessing its probably System.Net.SecurityProtocolType


Solution

  • First, you are probably assuming something that is false:

    enum MyEnum
    {
        One = 1;
        Two = 2;
    }
    
    var three = (MyEnum)3; //is this legal?
    

    Yes, it is, that will compile just fine. Its arguably a bad choice if MyEnum is not a bit field ([Flags] attribute), but its not enforced by the compiler. It probably would have been a good idea if the language had made a distinction between enums and flags because they are altogether different things but that train passed by a long time ago.

    If on the other hand the enum is a bit field, then oring is a must because the enumeration options are not exlcusive (that is precisely the whole point of flags) and it wouldn't be very useful if you had to come up with every possible valid combination when defining your enum type:

    [Flags]
    enum AnimalTraits
    {
         None         = 0
         Reptile      = 1 << 0,
         Mammal       = 1 << 1,
         Vertebrate   = 1 << 2,
         Invertebrate = 1 << 3,
         Amphybious   = 1 << 4,
         Acuatic      = 1 << 5,
         //etc.
    }
    
    var myAnimalFlags =  AnimalTraits.Invertebrate | 
                         AnimalTraits.Amphybious | 
                         AnimalTraits.Reptile
    

    Now you have an enum value that has those three flags set which can be handy for filtering data, setting options in some UI, etc.