3

I'm taking over a C# project and I have come across a concept that I'm unfamiliar with.

The project is using EF to create look-up tables from enums. The UI is accepting a multi-select input but the receiving model accepts a enum type, not a list/array or something else that would suggest plural.

The enum seems to have some recursive relationship

public enum Options
{
    None = 0,

    [Display(Name = @"On-site Security")]
    OnSiteSecurity = 1 << 0,

    [Display(Name = @"Gated Entry")]
    GatedEntry = OnSiteSecurity << 1,

    [Display(Name = @"Gated Entry - Video")]
    GatedEntryVideo = GatedEntry << 1,

    [Display(Name = @"Closed-Circuit TV")]
    CCTV = GatedEntryVideo << 1, ...

the look-up table has a Value column that with value that grow exponentially, 0,1,2,4,8,16,32,64,128,256,512

and finally the UI has a multi-select input where the value is the same number sequence as the look-up table. There is a sanitation function acting on the value like this (knockout.js)

self.Value = ko.computed({
    read: function () {
        var value = 0;
        $.each(self.Selected(), function (idxitem, item) {
            value |= item;
        });
        return value;
    },
    write: function (value) {

        $.each(self.Available(), function (idxitem, item) {
            if ((value & item.Value) > 0) {
                item.IsSelected(true);
            }
        });

        self.Normalize(value);
    },
    owner: self
});

I do not understand how this is supposed to accept plural selections.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Mark Hollas
  • 1,107
  • 1
  • 16
  • 44
  • The concept is called `flags enumeration', allowing you to store any combination of the enumeration values in a single type by treating the enumeration values as bit values (flags). See https://msdn.microsoft.com/en-us/library/ms229058(v=vs.100).aspx for details. – Paul-Jan Sep 23 '16 at 14:03
  • so that bitwise OR just concats the bit values of the value and the enum just knows how to treat it? what is the role of the exponent table value? sorry , just want to know what all the player are doing here – Mark Hollas Sep 23 '16 at 14:12

1 Answers1

1

It sounds like its implementing flags. This allows you to have a single Enum value that can represent several different values

Here's a short example

class Program
{
    static void Main(string[] args)
    {
        FlaggedEnum fruitbowl = FlaggedEnum.Apples | FlaggedEnum.Oranges | FlaggedEnum.Pears;

        Console.WriteLine(fruitbowl);

        Console.ReadLine();
    }
}

[Flags]
enum FlaggedEnum
{
    None = 0,
    Apples = 1,
    Pears = 2,
    Oranges = 4,
    Pineapples = 8
}

When you run this you get the output "Apples, Oranges, Pears". Its integer value would be 7 (4 + 2 + 1).

The reason for powers of two is due to their binary equivalents, 1 = 1, 2 = 10 4 = 100, 8 = 1000... So this gives 7 the value of 111.

I hope this puts you on the right path at least.

mark_h
  • 5,233
  • 4
  • 36
  • 52
  • this explains the number 56 in an pre-existing DB table where 56 is well out of the range of the enum... on a side, why? I get it that algorithms are cool and all, but the db servers are pretty fast these days, to me (in my inexperience) feels like overkill and a mask of smoke and mirrors (magic, if it were)...adding to the confusion, it concats on an OR (ish) operator...is this not confusing? – Mark Hollas Sep 23 '16 at 14:17
  • and a + 1 for having the same name and Initial as me :) – Mark Hollas Sep 23 '16 at 14:20
  • I find the use of an bitwise OR confusing too, you see it so rarely. You can write extension methods for your enum that hides this and allows you to use a more readable syntax (see http://stackoverflow.com/questions/9207612/extend-enum-with-flag-methods). Why would you use it? It involves very little data storage, you can set several values but only store one in the DB. – mark_h Sep 23 '16 at 14:31
  • @MarkHollas: Flags are a basic and commonly used concept in C# (and predecessor languages). To the original implementor, it might very well have felt like the most natural way to represent the data on the C# side. The manual OR operator in javascript is an unfortunate side effect of javascript not supporting the concept of Flags, and might indeed be an argument for using a different datatype or convert it when communicating between the js/c# layers. – Paul-Jan Sep 23 '16 at 14:31
  • @mark_h I can see that now. I was almost there on how I was thinking, but once having definitive clarification like this I will most likely implement it myself. I just gotta say though, sometimes I think there are so many patterns to make code run faster but seems to take away from readability and human comprehension. Computing will grow faster that those gains are likely negligible... so why not just make it readable...save more time on project maintenance (done by humans ) – Mark Hollas Sep 23 '16 at 14:41