A shortcut I often use in C when dealing with embedded APIs (communications protocols, primarily) allows me to edit an enum array and have everything else sized correctly after that:
typedef enum {
errortype1,
errortype2,
...
errortypeN,
ERROR_TYPE_MAX
} ErrorTypeList;
int errorcounts[ERROR_TYPE_MAX]; // Create array to hold a counter for each error type
As long as I add new error types before ERROR_TYPE_MAX then I can use that value everywhere else to give me the size of the enum.
In C#, however, this doesn't work as-is:
enum ErrorTypeList {
errortype1,
errortype2,
...
errortypeN,
ERROR_TYPE_MAX
};
int errorcounts[ErrorTypeList.ERROR_TYPE_MAX]; // Create array to hold a counter for each error type
This usage presents the error Array size cannot be specified in a variable declaration
which suggests using new
.
Is defining the array at runtime (via new
) my only option, or is there a way to accomplish this without a new, since the size of the enum isn't going to change after compilation?
Is there an alternative to this type of enum sizing pattern that better fits into c#?
If you want the size of an enum, you can do this:
enum Foo { A , B , C , ... , }
...
int[] someArray = new int[ sizeof(Foo) ] ;
But that won't give you what you want, since sizeof
returns the size of the object in octets (4 in this case, since an enum, by default wraps an Int32).
To get the number of values in the enum, do something like this:
enum Foo { A , B , C , ... , }
...
int[] someArray = new int[ Enum.GetValues(typeof(Foo)).Length ] ;
If you're planning on using the value of the enum to index into the array, you should note that this makes the [unwarranted] assumption that the enum's values start at 0 and increment by 1: a subsequent change to the enum's definition that violates the assumption will break things.
Further, if the enum has the [Flags]
attribute applied to it, then the domain of the enum is potentially [much] larger than the number of discrete values defined.
You would be better off to use a dictionary, thus:
[Flags]
enum Foo { Unknown = 0 , A = 1 , B = 2 , C = 4 , D = 8 , E = 16 , ... , }
...
Dictionary<Foo,SomeType> myDictionary = new Dictionary<Foo,SomeType>() ;
Now your code is much more flexible: you don't care about how the internals of the enum are arranged.
You might even pre-populate the dictionary with the expected set of keys (and throw an exception if handed a value other than the expected).
Edited To Note:
You could do something like this as well:
void DoSomething()
{
int[] someArray = CreateArrayBasedOnFoo<int>() ;
...
return ;
}
public T[] CreateArrayBasedOnFoo<T>()
{
Foo[] values = (Foo[]) Enum.GetValues(typeof(Foo)) ;
int lo = (int) values.Min() ;
int hi = (int) values.Max() ;
int domain = ( hi - lo ) + 1 ;
T[] instance = (T[]) Array.CreateInstance( typeof(T), new int[]{domain} , new int[]{lo} ) ;
return instance ;
}
The CreateArrayBasedOnFoo<T>()
method will hand back an array sized to fit the enum and whose lower bound is the smallest value of the enum. For instance, if you enum has 3 discrete values: 3, 5 and 7, the array handed back will be 5 elements in length and will have a lower bound of 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With