J.A.I.L.
J.A.I.L.

Reputation: 10794

How to allow or disallow bitwise operations

I'm looking for a certain type that allows perfomring flag / bitwise operations with other type but not with itself.

Imagine the following scenario:

public enum Suit : byte
{
    Spades      = 0x00, // bits: xx00 xxxx
    Hearts      = 0x10, // bits: xx01 xxxx
    Diamonds    = 0x20, // bits: xx10 xxxx
    Clubs       = 0x30  // bits: xx11 xxxx
}

public enum Rank : byte
{
    Ace         = 0x01, // bits: xxxx 0001
    _2          = 0x02, // bits: xxxx 0010
    //  ...
    _10         = 0x0A, // bits: xxxx 1010
    Jack        = 0x0B, // bits: xxxx 1011
    Queen       = 0x0C, // bits: xxxx 1100
    King        = 0x0D  // bits: xxxx 1101
}

I'd like to allow the following operation:

playingCardQueenOfHearts = Suit.Hearts| Rank.Queen;

But not the followings:

thisIsNonsenseInMyScenario = Suit.Spades | Suit.Hearts;
thisIsOdd = Rank.Jack | Rank.Ace;

Probably the enum isn't the best choice (in fact: it allows just the opposie I'm looking for). Is there any other type, or some way to archieve what I'm looking for?


I know I could cast to perform it (queenOfHearts = (byte)Suit.Hearts| (byte)Rank.Queen), but

a. Casting allows anything:

thisIsWhat = (int)Suit.Spades | (int)DayOfWeek.Sunday;

b. I'd like to restrict, or at least make difficult OR-ing elements of the same type:

thisIsNonsenseInMyScenario = Suit.Spades | Suit.Hearts;
thisIsOdd = Rank.Jack | Rank.Ace;

Upvotes: 0

Views: 52

Answers (1)

Tim S.
Tim S.

Reputation: 56556

I'd make a type (it could be a class or a struct) for this, e.g.

public struct Card
{
    public Suit Suit { get; private set; }
    public Rank Rank { get; private set; }
    public Card(Suit suit, Rank rank)
        : this()
    {
        this.Suit = suit;
        this.Rank = rank;
    }
    // include implementations for GetHashCode, Equals, ==, and !=
}

Use like

Card queenOfHearts = new Card(Suit.Hearts, Rank.Queen);

Upvotes: 3

Related Questions