Boolean operations on Enumerations

G

Guest

I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

.... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

.... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments on an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use the 'named
state' semantics that enum provides. So I want the 'state' to have both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
N

Nicholas Paldino [.NET/C# MVP]

Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that you
need to use an expression that returns a boolean value. That being said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.
 
G

Guest

Interesting.

Do you know the reasoning behind the boolean expression semantics?

Why does C# have the '!=' and the 'if()' semantics when performing simple
boolean logic?

I ask just in case there is something I should be testing for or doing in my
code.

Thanks so much for your response.

Shawnk

Nicholas Paldino said:
Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that you
need to use an expression that returns a boolean value. That being said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use the
'named
state' semantics that enum provides. So I want the 'state' to have both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
G

Guest

A clarification. I meant for assigment of values not testing.

I understand for the testing the enumeration state as in;

if ( target_state & desired_value != 0)
{
// Do something because the target state has the desired value
}

what about a bit wise OR for assignment (is what I meant) as in;

target_state += additional_value;
target_state = target_state | additional_value;

Will these expressions need the 'if()' context to work?

Thanks much for your help.

Shawnk

Shawnk said:
Interesting.

Do you know the reasoning behind the boolean expression semantics?

Why does C# have the '!=' and the 'if()' semantics when performing simple
boolean logic?

I ask just in case there is something I should be testing for or doing in my
code.

Thanks so much for your response.

Shawnk

Nicholas Paldino said:
Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that you
need to use an expression that returns a boolean value. That being said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use the
'named
state' semantics that enum provides. So I want the 'state' to have both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
N

Nicholas Paldino [.NET/C# MVP]

Shawnk,

Well, the reason is that conditional expressions should evaluate to true
or false.

In C++, you could do this:

if (x = 0)

And you would end up with it always evaluating to false, but at the same
time, you are always assigning to x. Usually, that's not the case.
Usually, you want to do a comparison, not an assignment.

The designers of C# decided to defend against such things, which is the
reason that for conditional statements (if, for, do, while), a boolean value
is required.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
Interesting.

Do you know the reasoning behind the boolean expression semantics?

Why does C# have the '!=' and the 'if()' semantics when performing simple
boolean logic?

I ask just in case there is something I should be testing for or doing in
my
code.

Thanks so much for your response.

Shawnk

Nicholas Paldino said:
Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that
you
need to use an expression that returns a boolean value. That being said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments
on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use the
'named
state' semantics that enum provides. So I want the 'state' to have
both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
N

Nicholas Paldino [.NET/C# MVP]

Shawnk,

Assignment expressions require a type that is the same, or can be
implicitly cast (if there is no cast) or an explicit cast. You don't need
the if statement (and I dont know how that would work if you did).


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
A clarification. I meant for assigment of values not testing.

I understand for the testing the enumeration state as in;

if ( target_state & desired_value != 0)
{
// Do something because the target state has the desired value
}

what about a bit wise OR for assignment (is what I meant) as in;

target_state += additional_value;
target_state = target_state | additional_value;

Will these expressions need the 'if()' context to work?

Thanks much for your help.

Shawnk

Shawnk said:
Interesting.

Do you know the reasoning behind the boolean expression semantics?

Why does C# have the '!=' and the 'if()' semantics when performing simple
boolean logic?

I ask just in case there is something I should be testing for or doing in
my
code.

Thanks so much for your response.

Shawnk

Nicholas Paldino said:
Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that
you
need to use an expression that returns a boolean value. That being
said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments
on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use
the
'named
state' semantics that enum provides. So I want the 'state' to have
both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
G

Guest

Nicholas,

So the semantics of boolean operators are intended (in C#) to have a
comparative effect (used for comparisons).

If I want to do an assignment to a bitmapped enum (FlagsAttribute) do I still
need the comparative context of the 'if()' wrapper?

I tryed the sample code below but received the following compile errors.

Error 1 Operator '&' cannot be applied to operands of type 'System.Enum' and
'System.Enum'
Error 2 Operator '|' cannot be applied to operands of type 'System.Enum' and
'System.Enum'
Error 3 Operator '+=' cannot be applied to operands of type 'System.Enum'
and 'System.Enum'
Error 4 Operator '!=' cannot be applied to operands of type 'System.Enum'
and 'int'

---------

using system;

public
class State_machine
{
Enum m_state; // State of machine

public
State_machine( Type Enum_typ )
{
m_state = ( Enum ) Activator.CreateInstance( Enum_typ );
}

public
bool Test_state( Enum target_sta )
{
if ( (m_state & target_sta) != 0 )
{
return true;
}
else
{
return false;
}
}

public
bool Or( Enum incoming_state )
{
if ( (m_state | incoming_state) != 0 )
{
return true;
}
else
{
return false;
}
}

public
bool Add_state( Enum additional_sta )
{
if ( (m_state += additional_sta) != 0 )
{
return true;
}
else
{
return false;
}
}

-------

Also I tryed the code without the '()' wrapers around the core boolean
activity

if ( m_state & target_sta != 0 )

only to get the error;

Error 1 Operator '!=' cannot be applied to operands of type 'System.Enum'
and 'int'



Nicholas Paldino said:
Shawnk,

Well, the reason is that conditional expressions should evaluate to true
or false.

In C++, you could do this:

if (x = 0)

And you would end up with it always evaluating to false, but at the same
time, you are always assigning to x. Usually, that's not the case.
Usually, you want to do a comparison, not an assignment.

The designers of C# decided to defend against such things, which is the
reason that for conditional statements (if, for, do, while), a boolean value
is required.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
Interesting.

Do you know the reasoning behind the boolean expression semantics?

Why does C# have the '!=' and the 'if()' semantics when performing simple
boolean logic?

I ask just in case there is something I should be testing for or doing in
my
code.

Thanks so much for your response.

Shawnk

Nicholas Paldino said:
Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that
you
need to use an expression that returns a boolean value. That being said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments
on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use the
'named
state' semantics that enum provides. So I want the 'state' to have
both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
G

Guest

Nicholas,

Just so you know. I'm not checking for type and value in these examples.
In the 'real code' I do all the type checking and value checking
(Enum.IsDefined).

I can do the following -

Enum m_state;

m_state = New_value;

but to add 'additional states' as in;

m_state = m_state | New_value;
m_state = m_state | New_value_01 | New_value_02;

are the assignment semantics I was thinking of.

Thanks so much for your help on this :)

Shawnk

Nicholas Paldino said:
Shawnk,

Assignment expressions require a type that is the same, or can be
implicitly cast (if there is no cast) or an explicit cast. You don't need
the if statement (and I dont know how that would work if you did).


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Shawnk said:
A clarification. I meant for assigment of values not testing.

I understand for the testing the enumeration state as in;

if ( target_state & desired_value != 0)
{
// Do something because the target state has the desired value
}

what about a bit wise OR for assignment (is what I meant) as in;

target_state += additional_value;
target_state = target_state | additional_value;

Will these expressions need the 'if()' context to work?

Thanks much for your help.

Shawnk

Shawnk said:
Interesting.

Do you know the reasoning behind the boolean expression semantics?

Why does C# have the '!=' and the 'if()' semantics when performing simple
boolean logic?

I ask just in case there is something I should be testing for or doing in
my
code.

Thanks so much for your response.

Shawnk

:

Shawnk,

Actually, C# does have the &, +=, and | operators. It's just that
you
need to use an expression that returns a boolean value. That being
said,
you need to do this:

if (l_prt_sta & portState.Active != 0)

That should work.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments
on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use
the
'named
state' semantics that enum provides. So I want the 'state' to have
both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?
 
T

Tom Porterfield

Shawnk said:
Nicholas,

Just so you know. I'm not checking for type and value in these examples.
In the 'real code' I do all the type checking and value checking
(Enum.IsDefined).

I can do the following -

Enum m_state;

m_state = New_value;

but to add 'additional states' as in;

m_state = m_state | New_value;
m_state = m_state | New_value_01 | New_value_02;

are the assignment semantics I was thinking of.

Those will work fine. A short example:

[Flags]
private enum portState
{
Unknown = 0
, Open = 1
, Active = 2
, Secure = 4
}

static void Main(string[] args)
{
portState ps = portState.Unknown;
ps |= portState.Secure | portState.Open;
Console.Write(ps.ToString());
// output is Open, Secure
}
 
M

Mythran

Shawnk said:
I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

myEnum l_prt_sta;

... // Bitwise AND to test port state

if ( l_prt_sta & portState.Active )
{
// Do an active port process
}

... // Add new states to port state

l_prt_sta += Requester_trace_cutoff |
Trace_cutoff_due_to_protected_status;

-------------------

The operations above (&, +=, |) are not provided in C#.

Unfortunately the Enum class does not have the value semantics to
manipulate
the
enumeration as as a state machine value.

I could use Convert.ToInt32, Convert.ToInt64, ect,
perform the boolean operation,
and then reconvert the value back.

Is there a better way to implement boolean operations and assignments on
an
enum?

Thanks ahead of time for any responses.

Shawnk

PS. I know about BitArray and BitVector32 but I would like to use the
'named
state' semantics that enum provides. So I want the 'state' to have both
boolean
vector and enumeration semantics.


PPS. ALso what is the best way to do multiple enum value assignments?

Here's a few utility methods to use with bit flags :) Used to use these in
C/C++ and now for C# :)

/// <summary>
/// Checks to see if a bit is set in a set of bit flags.
/// </summary>
/// <param name="Flags">
/// The flags that may contain the specified bit.
/// </param>
/// <param name="Bit">
/// The bit to check.
/// </param>
/// <returns>
/// Returns <see langword="true"/> if the bit is set; otherwise, returns
/// <see langword="false"/>.
/// </returns>
public static bool IsBitSet(int Flags, int Bit)
{
return (Flags & Bit) == 0;
}

/// <summary>
/// Toggles a bit on or off.
/// </summary>
/// <param name="Flags">The flags in which to toggle the bit.</param>
/// <param name="Bit">The bit to toggle.</param>
public static void ToggleBit(ref int Flags, int Bit)
{
Flags ^= Bit;
}

/// <summary>
/// Set a bit in a flags argument.
/// </summary>
/// <param name="Flags">
/// The flags argument in which to set the bit.
/// </param>
/// <param name="Bit">The bit to set.</param>
public static void SetBit(ref int Flags, int Bit)
{
Flags |= Bit;
}

/// <summary>
/// Remove a bit in a flags argument.
/// </summary>
/// <param name="Flags">
/// The flags argument in which to remove the bit.
/// </param>
/// <param name="Bit">The bit to remove.</param>
public static void RemoveBit(ref int Flags, int Bit)
{
Flags &= ~(Bit);
}


To use, just pass in the Flags and Bit (Flags arg is a ref'ed arg). You
will need to modify the methods to work with enumerations though ...
unfortunately I haven't had the time to modify them myself.

HTH,
Mythran
 
J

John B

Shawnk said:
I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

In addition to the other replies, bear in mind that if you want a
bitmask enum you must explicitly declare it as so.
FlagsAttribute only marks that it CAN be used as a bitmask.

ie
enum portState{
Unknown =0, //??
Open = 2<<0,
Active = 2<<1,
Secure = 2<<2,
....

You get the idea
<...>

JB
 
G

Guest

Tom,

Thank you so much for your reply.
I tryed the solution but it does not work for generalized state machine
designs based on an Enum state space. Here is the modified version of your
code.

using System;

public class Demo
{

[Flags]
private enum portState
{
Unknown = 0
, Open = 1
, Active = 2
, Secure = 4
}

static void Main(string[] args)
{
portState l_ps = portState.Unknown;
l_ps |= portState.Secure | portState.Open;
Console.WriteLine(l_ps.ToString());

// output is Open, Secure

Enum l_state_enm;

l_state_enm = ( Enum ) Activator.CreateInstance( typeof
(portState) );

Console.WriteLine( l_state_enm.GetType().Name );

// output is portState

l_state_enm = portState.Unknown;

// Can not use boolean operations on Enumeration

l_state_enm |= portState.Secure | portState.Open; // Compiler Error CS0019
}

} // End_of_class



Tom Porterfield said:
Shawnk said:
Nicholas,

Just so you know. I'm not checking for type and value in these examples.
In the 'real code' I do all the type checking and value checking
(Enum.IsDefined).

I can do the following -

Enum m_state;

m_state = New_value;

but to add 'additional states' as in;

m_state = m_state | New_value;
m_state = m_state | New_value_01 | New_value_02;

are the assignment semantics I was thinking of.

Those will work fine. A short example:

[Flags]
private enum portState
{
Unknown = 0
, Open = 1
, Active = 2
, Secure = 4
}

static void Main(string[] args)
{
portState ps = portState.Unknown;
ps |= portState.Secure | portState.Open;
Console.Write(ps.ToString());
// output is Open, Secure
}
 
G

Guest

John,

That's true. I forgot to do the ' = Power of two' value assignments
in my example.

Thanks for noting that :)

Shawnk

John B said:
Shawnk said:
I would like to perform various boolean operations on bitmapped
(FlagsAttribute)
enum types for a state machine design as in;

-------------------

[FlagsAttribute]
enum portState {
Unknown,
Open,
Active,
Secure,
Requester_trace_requested,
Requester_trace_cutoff,
Requester_trace_complete,
Requester_trace_valid,
Trace_cutoff_due_to_timeout,
Trace_cutoff_due_to_privacy_rights,
Trace_cutoff_due_to_protected_status
Close
}

In addition to the other replies, bear in mind that if you want a
bitmask enum you must explicitly declare it as so.
FlagsAttribute only marks that it CAN be used as a bitmask.

ie
enum portState{
Unknown =0, //??
Open = 2<<0,
Active = 2<<1,
Secure = 2<<2,
....

You get the idea
<...>

JB
 
G

Guest

Mythran,

I'm trying to write a simple state machine in C# that can
use any enumeration type. Your solution will not work in C#
since the Enum class is pretty worthless basis for state machines.
Who ever designed this had no clue on maintaining value semantics
for an enumerated type (or on writing simple state machines, let
alone elegant state machines).

(Its the C# language - your solutions are great :)

In fact the Enum class is a pretty worthless design in general
since the MS docs claim you can '..treat the enumeration as a bit field'.
However, I could be wrong, and thus this post...

Here is a sample of your solution written for a simple state machine.

public static void SetBit(ref Enum Flags, Enum Bit)
{
Flags |= Bit; // Compiler Error CS0019
}

Thanks you for your reply.
 
G

Guest

Tom,

Note : A better way to create an Enum instance is -

Enum l_state_enm;
int l_initial_value = 3;

l_state_enm = (Enum) Enum.ToObject( typeof (portState),
l_initial_value );
 
T

Tom Porterfield

Shawnk said:
Thank you so much for your reply.
I tryed the solution but it does not work for generalized state machine
designs based on an Enum state space. Here is the modified version of your
code.

using System;

public class Demo
{

[Flags]
private enum portState
{
Unknown = 0
, Open = 1
, Active = 2
, Secure = 4
}

static void Main(string[] args)
{
portState l_ps = portState.Unknown;
l_ps |= portState.Secure | portState.Open;
Console.WriteLine(l_ps.ToString());

// output is Open, Secure

Enum l_state_enm;

l_state_enm = ( Enum ) Activator.CreateInstance( typeof
(portState) );

Console.WriteLine( l_state_enm.GetType().Name );

// output is portState

l_state_enm = portState.Unknown;

// Can not use boolean operations on Enumeration

l_state_enm |= portState.Secure | portState.Open; // Compiler Error
CS0019 }

} // End_of_class

Since Enums can have different underlying types, and since you have created
the instance in such a way that neither the compiler, nor the runtime for
that matter, have any idea what the type of this enum is, it can't resolve
l_state_enm with portState.Secure. The following will work, presented as
example as I'm sure it could be cleaned up just a bit:

static void Main(string[] args)
{
portState l_ps = portState.Unknown;
l_ps |= portState.Secure | portState.Open;
Console.WriteLine(l_ps.ToString());

// output is Open, Secure

Enum l_state_enm;

l_state_enm = (Enum)Activator.CreateInstance(typeof(portState));

Console.WriteLine(l_state_enm.GetType().Name);

// output is portState

l_state_enm = portState.Unknown;

int tmp = Convert.ToInt32(l_state_enm);

tmp |= (int)portState.Open | (int)portState.Secure;
l_state_enm = (portState)tmp;
Console.WriteLine(l_state_enm);
// output is Open, Secure
}
 
G

Guest

Tom,

That is exactly the design I currently have but I'm
favoring the 'BitArray' class over 'int' for the boolean value semantics
and the boolean iteration - foreach( bool l_bit_emr in my_bit_map).

The 'Bit_map_cls' I have designed is based on
BitArray for the boolean semantics which has boolean
value semantics just like your example with the 'int'
(numeric expression of state vs BitArray expression of state
semantics).

Also, in my current design (which I find far too complex),
I track the underlying type of the core enum (the heart
of the state machine I'm trying to design). This allows
the specfication of both the bit vector limit (sizeof
underlying type) and the bit vector lenght (the number
of bits that are actually defined).

I use the following expression to track the bit vector size (limit).

TypeCode l_enm_bas_cod;
l_enm_bas_cod = Type. GetTypeCode( p_trg_enm_typ );

switch( l_enm_bas_cod )
{
// ....
case TypeCode.Char:
case TypeCode.Int16:
case TypeCode.UInt16:
l_trg_enm_lmt = 16;
break;

case TypeCode.Int32:
case TypeCode.UInt32:
l_trg_enm_lmt = 32;
break;

// ....
}

This results in (as can be seen) a really, really poor design (IMHO)
because of the added complexity due to Enum not having 'real' value semantics.

I'm going to put up a new post on simple state machine designs to verify
this lack of value semantics for enumerations in C#.

Thanks so much for all your help. It is very appreciated.

Shawnk

PS. When I do the underlying conversions I use a switch statement on size
so I can support 8, 16, 32, and 64 bit maps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top