0

I have the following enums defined in my code:

[Flags]
public enum Symbol
{
    A,
    B,
}

public enum Production
{
    AA = Symbol.A | Symbol.A,
    AB = Symbol.A | Symbol.B,
    BA = Symbol.B | Symbol.A, // <- this will obviously not work
}

I was planning to make use of enums as they eventually would prevent unwanted Symbols to be used for Productions. The problem is that the following code does not produce the output that I'm after:

Productions product1 = (Productions) (Symbol.A | Symbol.A); // Production.AA
Productions product2 = (Productions) (Symbol.A | Symbol.B); // Production.AB
Productions product3 = (Productions) (Symbol.B | Symbol.A); // Production.AB (and not Production.BA as I would like)

I completely understand why this is happening, but was wondering if there is a combination of bitwise operators that I could use to make it work as I originally intended?

Or maybe in general I'm trying to use enums in a incorrect way, therefore should switch to chars or even custom structs?

MonkeyCoder
  • 2,600
  • 2
  • 28
  • 30
  • I honestly don't understand what you are trying to achieve here. – Oded Oct 27 '12 at 15:47
  • I was hoping to use enums for grammar parsing (with a defined set of symbols). This would mean that Symbol.A and Symbol.B can be used to construct a word that has been defined in the `Production` enum. But the implementation that I've presented doesn't allow for constructing `Production.BA`. Hope that clears it a bit. – MonkeyCoder Oct 27 '12 at 16:04
  • On a side note: Enums decorated with `[Flags]` should be plural. Normal enums should be singularized. SO Reference http://stackoverflow.com/questions/1405851/enum-naming-convention-plural – Silvermind Oct 27 '12 at 16:16
  • Your fundamental problem is that X | Y is the same as Y | X. That is the way the OR operator works. Back to the drawing board. – Steve Wellens Oct 27 '12 at 16:21
  • Thanks Steve, as I've mentioned in my post - I do understand *why* this is happening, I'm just wondering if there is a *combination* of bitwise operators that I could use to achieve what I want. – MonkeyCoder Oct 27 '12 at 16:26
  • Note that simply adding `Flags` to an enumeration will *not* automatically make it support flag functionality. The values will still receive default, sequential, values. You must give them the values `0x1, 0x2, 0x4, 0x8` and so forth yourself. – GregRos Oct 27 '12 at 17:19
  • Can the down-voter leave me a comment so that I could potentially improve the question/knowledge? – MonkeyCoder Nov 08 '12 at 11:21

3 Answers3

2

Well, because you need to take care of the order of A and B than you should use some operation that is not commutative. I would better suggest the approach where each position should have the assigned weight and you can have simple addition of symbols with weights. Since Enums are ints you can assign to each position a weight of 10^i where i is the zero-based index of the position looking from right to left. Even then you can have calculations for even more Symbols. This is like with classic Arabic numbers but with your symbols instead of regular digits. The code can be like this:

    [Flags]
    public enum Symbol
    {
        A,
        B,
    }

    public enum Production
    {
        AA = Symbol.A *10 + Symbol.A, //0
        AB = Symbol.A *10 + Symbol.B, //1
        BA = Symbol.B *10 + Symbol.A, //10
    }
Nikola Davidovic
  • 8,556
  • 1
  • 27
  • 33
  • I think this is the closest to what I wanted to achieve, eventually I skipped the use of enums as they don't go nicely in this particular scenario. Thanks! – MonkeyCoder Nov 08 '12 at 11:14
0

You are trying to perform pattern matching. This is not what enums are for. Languages such as F# have a great mechanism built-in to do this, for example:

match expression with 
| pattern_1 -> expression_1 
| pattern_2 -> expression_2 
| pattern_n -> expression_n

But C# does not have this [yet]. There is a great project to add a library to C# to give it this functionality called Functional C#. I think that library is your best bet.

Austin Henley
  • 4,625
  • 13
  • 45
  • 80
0

As you want to keep information about both the value and posititon, you would need to use different enum value for different values at different positions:

[Flags]
public enum Symbol {
  FirstA = 1,
  FirstB = 2,
  SecondA = 4,
  SecondB = 8
}

public enum Production {
  AA = Symbol.FirstA | Symbol.SecondA,
  AB = Symbol.FirstA | Symbol.SecondB,
  BA = Symbol.FirstB | Symbol.SecondA
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005