Monday, August 01, 2005

& and && in C# - Part II

Revisiting & AND && operator, in the part I, I have talked about them and written a very short code snippet, in part II, I will discuss how we can write more useful code using these operators.
Consider we have to write a user control and it has several flags like( IsVissible, IsEditable, IsDraggable etc etc ), common practise is creating boolean variable for each flag, but we can get away with all boolean flags, using one single integer variable .. how ? let me explain it.

We will declare one integer variable ( say name it as m_AllFlags ) and each bit within m_AllFlags variable would represent the current state of one of the flags. we would then use bit manipulations to set and to get each flag.
First, we need to set up constants that indicate the various flags for our UC, these flags should each be a different power of 2 to ensure that each bit is used by only one flag. we will set bits of flags accordingly to the current state of each flag.

int flags = 0 ; ( means that all flags are false (none of the bits are set) )
const int TESTCONTROL_VISIBLE = 1;
const int TESTCONTROL_EDITABLE = 2;
now we will write property for each flags .. lets have a look at IsVisible property

public bool IsVisible
{
set
{
if( value )
{
m_AllFlags = m_AllFlags | TESTCONTROL_VISIBLE;
}
else
{
m_AllFlags = m_AllFlags ^ TESTCONTROL_VISIBLE;
}
}
get
{
if( (m_AllFlags & TESTCONTROL_VISIBLE) == TESTCONTROL_VISIBLE )
{
return true;
}
else
{
return false;
}
}
}

so if user send TRUE we will do a inclusive OR and if it is FALSE we will do exclusive OR, and at the time GET we will do a bitwise AND , if the returned value matches with the constant then we will return TRUE else FALSE. Those who are not yet familiar with inclusive/exclusive OR the following table will help you to understand the concept ..
The Bitwise Inclusive OR Function Bit in op1 Corresponding Bit in op2 Result
0 0 0
0 1 1
1 0 1
1 1 1
The Bitwise Exclusive OR (XOR) Function Bit in op1 Corresponding Bit in op2 Result
0 0 0
0 1 1
1 0 1
1 1 0

lets see what happen if caller pass TRUE to this property ...
m_AllFlags = m_AllFlags | TESTCONTROL_VISIBLE; [ m_AllFlags = 0 inclusive OR 1, so now m_AllFlags = 1 ]

now if caller does a GET the following line will execute ...
if( (m_AllFlags & TESTCONTROL_VISIBLE) == TESTCONTROL_VISIBLE ) it does a bitwise AND then compare the value with a constant, based on the comparison result it returns TRUE or FALSE,
For those are not yet familiar with bitwise AND .. please have a look at the following table ..
The Bitwise AND Function Bit in op1 Corresponding Bit in op2 Result
0 0 0
0 1 0
1 0 0
1 1 1
(m_AllFlags & TESTCONTROL_VISIBLE) == TESTCONTROL_VISIBLE ) [ 1 bitwiseAND 1 == 1 , hence it returns TRUE ]

Let us consider, after this caller set the flag as FALSE
m_AllFlags = m_AllFlags ^ TESTCONTROL_VISIBLE; [ m_AllFlags = 1 exclusive OR 1, so now m_AllFlags = 0 ]

now if we do a GET
(m_AllFlags & TESTCONTROL_VISIBLE) == TESTCONTROL_VISIBLE ) [ 0 bitwiseAND 1 == 1 , hence it returns FALSE ]

Most important point about the above code snippet is .. when the caller pass a flag value .. we need to first check the current bit value and if it is same we will just ignore it else we will set the value,[ if( (m_AllFlags & TESTCONTROL_VISIBLE) == TESTCONTROL_VISIBLE ) { //caller has passed the same value .. ignore it.} ].
So we can end up with one single int variable which will hold all the flags, I have uploaded the entire project code in this following location( Operator test source code )please download and play with it if you feel interested.

Note : Thanks to Palb for his comments.

Neo













No comments: