Click to See Complete Forum and Search --> : Operator Overload for enumeration


If_Mel_YES_Else_NO
October 1st, 2005, 04:44 PM
I was really hoping that since enum types are objects just like every other class, that I could create custom operator overloads with them. However, I can't seem to find a way to do it. I would like to overload the ++ operator, but you can't seem to add an overload method unless it has to do with the containing class.
Ex:
Public enum Baud_Rates
{
BR_4800 = 4800,
BR_9600 = 9600,
BR_38400 = 38400
}

void test()
{
Baud_Rates br = Baud_Rates.BR_4800;
br++;
br++;
}

What I would like is to end up with a result of br == BR_38400, but instead I get br == 4802. Does anyone know of a trick to overload operators that work with Enums?

jmcilhinney
October 1st, 2005, 08:14 PM
It ain't pretty but:public enum Baud_Rates
{
BR_4800 = 4800,
BR_9600 = 9600,
BR_38400 = 38400
}

void test()
{
Baud_Rates br = Baud_Rates.BR_4800;
br = (Baud_Rates)Enum.GetValues(typeof(Baud_Rates)).GetValue(Array.IndexOf(Enum.GetValues(typeof(Baud_Rates)), br) + 1);
MessageBox.Show(br.ToString());
}
You could write a generic method that took a value and a type and returned the next enumerated value of that type. You could also have it loop back to the first value if the passed value is the last.

jmcilhinney
October 1st, 2005, 08:46 PM
...and here is that method:public enum Baud_Rates
{
BR_4800 = 4800,
BR_9600 = 9600,
BR_38400 = 38400
}

void test()
{
Baud_Rates br = Baud_Rates.BR_4800;
MessageBox.Show(br.ToString());
br = (Baud_Rates)this.GetNextValue(typeof(Baud_Rates), (int)br, true);
MessageBox.Show(br.ToString());
br = (Baud_Rates)this.GetNextValue(typeof(Baud_Rates), (int)br, true);
MessageBox.Show(br.ToString());
br = (Baud_Rates)this.GetNextValue(typeof(Baud_Rates), (int)br, true);
MessageBox.Show(br.ToString());
}

private int GetNextValue(Type enumType, int currentValue, bool loop)
{
Array values = Enum.GetValues(enumType);
int index = -1;

// Find the index of the current value.
for (int i = 0; i < values.Length; i++)
{
if (currentValue == (int)values.GetValue(i))
{
index = i;
break;
}
}

if (index == -1)
{
// The current value is not valid for the specified type so throw an exception.
throw new Exception("Invalid current value.");
}

if (index == values.GetUpperBound(0))
{
if (loop)
{
// Loop from the maximum value to the minimum.
index = 0;
}
else
{
// The current value is the maximum so either return the current value or throw an exception.
return currentValue;
}
}
else
{
// Get the index of the next value.
++index;
}

return (int)values.GetValue(index);
}

jhammer
October 2nd, 2005, 03:00 AM
Or you can wrap the enum in a class:


class YourEnumClass
{
private enum YourEnum
{
Enum1,
Enum2,
(...)
}

private YourEnum _value;
public YourEnum Value
{
get { return _value; }
set { _value = value; }
}

public YourEnum Enum1
{
get { return YourEnum.Enum1}
}
(...)

public bool operator==(YourEnumClass c1, YourEnumClass c2)
{
return c1.Value == v2.Value;
}
}

I hope you understand the method. (little hard-work)

If_Mel_YES_Else_NO
October 3rd, 2005, 08:20 AM
Thanks jhammer, I had a feeling it would come to that. At least this way I can overload the ++, and maybe even declare some static properties to mimic the way you access an enum's values.

<code>
public class Baud_Rates
{
private int m_nVal;
private static int[] m_nVals = new int[] {4800, 9600, 38400};

public static Baud_Rates BR_4800
{
get {
Baud_Rates br = new Baud_Rates();
br.m_nVal = m_nVals[0];
return br;
}
}
public static Baud_Rates BR_9600
{
get {
Baud_Rates br = new Baud_Rates();
br.m_nVal = m_nVals[1];
return br;
}
}
public static Baud_Rates BR_38400
{
get {
Baud_Rates br = new Baud_Rates();
br.m_nVal = m_nVals[2];
return br;
}
}

public static Baud_Rates operator++(Baud_Rates br)
{
Baud_Rates brNew = new Baud_Rates();
int i = 0;
for (i = 0; i < m_nVals.Length; i++)
{
if (m_nVals[i] == br.m_nVal)
{
break;
}
}
brNew.m_nVal = m_nVals[(i+1)%3];
return brNew;
}

public static void operator=(Baud_Rates br1, Baud_Rates br2)
{
br1.m_eBR = br2.m_eBR;
}
}
</code>

MadHatter
October 3rd, 2005, 09:47 AM
just create an iterator, and use it (its not an operator overload, but does the iteration for you like ++ would).

e.Current will be the int value of your enum. you could easily add a set current method that would search the _values array and set _value to the index of the enum value passed in.

namespace ConsoleApplication9 {
using System;
using System.Collections;
class Class1 {
[STAThread]
static void Main(string[] args) {
IEnumerator e = new EnumIterator(typeof(BaudRates));
while(e.MoveNext()) {
BaudRates b = (BaudRates)e.Current;
Console.WriteLine(b);
Console.WriteLine(e.Current);
}

Console.ReadLine();
}
}

public enum BaudRates {
BR_4800 = 4800,
BR_9600 = 9600,
BR_38400 = 38400
}

public class EnumIterator : IEnumerator {
Type _t;
int _value = 0;
int[] _values;
int _current = 0;

public EnumIterator(Type typeOfEnum) {
if(typeOfEnum.BaseType != typeof(Enum)) throw new ArgumentException("typeOfEnum is not an enum");
_t = typeOfEnum;
Array vals = Enum.GetValues(_t);
_values = new int[vals.Length];
for(int i = 0; i < vals.Length; i++) {
_values[i] = (int)vals.GetValue(i);
}
}
public void Reset() {
_value = 0;
}

public object Current {
get {
return _current;
}
}

public bool MoveNext() {
bool canMove = _value < _values.Length;
if(canMove) {
_current = _values[_value];
_value++;
}else Reset();
return canMove;
}
}
}

If_Mel_YES_Else_NO
October 5th, 2005, 10:13 AM
Interesting idea MadHatter, but I prefer encapsulating as much as possible so that users of my code don't have to do anything different than normal.

Old Way:
enum BaudRates {BR_4800, BR_9600, BR_38400}
main()
{
BaudRates x = BaudRates.BR_4800;
x++;
x++;
}
result gives x == BR_38400

My new Way:
Class BaudRates{...emplemented above...}
main()
{
BaudRates x = BaudRates.BR_4800;
x++;
x++;
}

Looks nearly identical with result still x == BR_38400. BUT now x also has the value of 38400. This comes up a lot when you work with a bunch of guys who hate learning new ways to get things done :)