0

Here is what i am trying to do.

I have two bit fields in my database:

Archived(bit) Deleted(bit)

What i would like to do is calculate a int depending on their vaules.

As an example, this would be in my model:

class Person {

Int32 Status {get;set;}

}

If Archived = true set the status to 1,

If Deleted = true set the status to 2,

If both are false, set the status to 0.

I want to do this with out using If statements, maybe there is some sort of boolean arithmetic that i can use?

xqwzid
  • 520
  • 3
  • 14

2 Answers2

5

Why don't use an enum?

[Flags]
public enum PersonState
{
    None = 0,
    Archived = 1,
    Deleted = 2,
    Both = Archived | Deleted
}

class Person
{
    private PersonState status;

    public PersonState Status
    {
        get { return this.status; }
        set { this.status = value; }
    }

    public bool IsArchived
    {
        get
        {
            return (this.status & PersonState.Archived) != 0;
        }
        set
        {
            if (value)
                this.status |= PersonState.Archived;
            else
                this.status &= ~PersonState.Archived;
        }
    }

    public bool IsDeleted
    {
        get
        {
            return (this.status & PersonState.Deleted) != 0;
        }
        set
        {
            if (value)
                this.status |= PersonState.Deleted;
            else
                this.status &= ~PersonState.Deleted;
        }
    }
}

You can directly cast an enum value to integer.

int x = (int)person.Status;

And you can do the contrary, if you have an int.

person.Status = (PersonState)integerValue;

Also if you don't provide the possibility that Deleted and Archived can coexists together this is actually a possibility with booleans. The number of possible values encoded by n boolean values is 2^n, so, since you have 2 booleans, you have 4 possible values, 00, 01, 10 and 11.

The problem is in the problem itself: it is wrong to encode that information with booleans. It should be an enum with only 3 possible values also in the DB.

Salvatore Previti
  • 8,956
  • 31
  • 37
  • But IsArchived and IsDeleted need to be initially set from the database, how do i pipe this into the works? – xqwzid Oct 30 '11 at 03:45
  • Edited just now, in this way you can access for read and for write both in enum and in boolean properties. – Salvatore Previti Oct 30 '11 at 03:54
  • Note that in this case, as i wrote it, Both means both archived and deleted while None means not archived and not deleted. – Salvatore Previti Oct 30 '11 at 03:57
  • If `Both` isn't a possibility you want to consider, I'd remove the `[Flags]` tag, the `Both` value, and leave it as an enum. You should only keep it as a `[Flags]` if you want to allow both to be set at the same time. – Merlyn Morgan-Graham Oct 30 '11 at 04:13
  • Yes but the problem is that if you remove flags you will get a compiler error if you try to use binary arithmetic for write, of course, because it will provide you values not allowed. in that case you need to do a cast to integer. The problem is in the problem itself: it is wrong to encode that information with booleans in the DB, it should be an enum with only 3 possible values also in the DB. – Salvatore Previti Oct 30 '11 at 04:15
  • I removed the [Flags]. As i said earlier i will never need both. Only the Archived or Deleted bits will ever be set to true/false. The whole purpose of this was was to provide a unified Int to a webgrid so i could sort the column, which works fantastic now. Thanks for your input(s) they have been greatly appreciated. – xqwzid Oct 30 '11 at 04:26
  • @Salvatore: Agreed. +1 for the original answer, and still +1 because of your response and the edit. – Merlyn Morgan-Graham Oct 30 '11 at 04:26
  • So for what i understand, you guys are saying i should actually create the enum in the database itself? – xqwzid Oct 30 '11 at 04:31
  • I would prefer to use an enum in the DB yes, it seems to me the more clean solution possible. And since you have that enum, you can assign the enum directly to property Status and viceversa, without the need to write boolean values. – Salvatore Previti Oct 30 '11 at 04:34
  • How do you do enums in a DB? Does Entity Framework support it also? – xqwzid Oct 30 '11 at 04:35
  • What DB are you using and what version? – Salvatore Previti Oct 30 '11 at 04:38
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/4595/discussion-between-xqwzid-and-salvatore-previti) – xqwzid Oct 30 '11 at 04:42
2

You can write Convert.ToInt32(Archived) + 2 * Convert.ToInt32(Deleted).

However, don't. Using ifs will result in much more readable code, and will probably be a little faster too.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964