Enumerators
-
In the spirit of the new charter of this forum - "wicked code" - I see this as wicked code... I started programming long before many of the rest of you. Over the years, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy regarding ensuring that data is valid before trying to use it. One of the problems I encountered was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually values - either modified by the user, or incorrectly set or interpreted by the programmer. So I came up with this method that I have include i pretty much every program I write:
public static T IntToEnum<T>(int value, T defaultValue) { T enumValue = (Enum.IsDefined(typeof(T), value)) ? (T)(object)value : defaultValue; return enumValue; }
The purpose of the method is to allow the programmer to initialize a data member of a specified enumerator type to a value contained in the ordinal list. The problem this method addresses is that if the programmer retrieves an enum ordinal value as an int type, and wants to initialize an enum data member, he really has no programmatic idea if the value represents a valid ordinal. He simply tries to set it, and hope for the best (handling an exception if the assignment goes sideways on him). This method allows the programmer to make the same attempt, but with controlled results and thereby avoiding the inevitable exception generated when an invalid ordinal value is used. Usage goes something like this:
enum SomeEnum { Zero=0, Five=5, Six=6, Eight=8 };
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = IntToEnum(5, SomeEnum.Zero);// this will result in SomeEnum.Zero because the value (4) isn't a valid ordinal in the enumerator
value = IntToEnum(4, SomeEnum.Zero);.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001You could apply generics to this as well to reduce how many times you have to create this in your code. :D
public static U ToEnum<T, U>(T value, U defaultValue) { return (Enum.IsDefined(typeof(U), value)) ? (U)((object)value) : defaultValue; }
And made into an extension method, if you so choose.
-
You could apply generics to this as well to reduce how many times you have to create this in your code. :D
public static U ToEnum<T, U>(T value, U defaultValue) { return (Enum.IsDefined(typeof(U), value)) ? (U)((object)value) : defaultValue; }
And made into an extension method, if you so choose.
What's the point of type T? You might as well just use object and remove the unnecessary cast. Personally, I would also eliminate the repeated typeof(U) and cache the Type, but that's just me.
-
What's the point of type T? You might as well just use object and remove the unnecessary cast. Personally, I would also eliminate the repeated typeof(U) and cache the Type, but that's just me.
True, you could just drop that. I just got generic happy. As for caching the typeof(U), since that is going to change per method instance - I don't know if you'd get anything by caching that. Plus, I'm not sure how you'd simply do that without adding a bit of overhead to the whole process. Typeof would be done at compile time, so it should be fairly efficient as is.
-
True, you could just drop that. I just got generic happy. As for caching the typeof(U), since that is going to change per method instance - I don't know if you'd get anything by caching that. Plus, I'm not sure how you'd simply do that without adding a bit of overhead to the whole process. Typeof would be done at compile time, so it should be fairly efficient as is.
Oh, right, this is a method, not a class; I usually write a generic class and cache the Type.
-
In the spirit of the new charter of this forum - "wicked code" - I see this as wicked code... I started programming long before many of the rest of you. Over the years, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy regarding ensuring that data is valid before trying to use it. One of the problems I encountered was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually values - either modified by the user, or incorrectly set or interpreted by the programmer. So I came up with this method that I have include i pretty much every program I write:
public static T IntToEnum<T>(int value, T defaultValue) { T enumValue = (Enum.IsDefined(typeof(T), value)) ? (T)(object)value : defaultValue; return enumValue; }
The purpose of the method is to allow the programmer to initialize a data member of a specified enumerator type to a value contained in the ordinal list. The problem this method addresses is that if the programmer retrieves an enum ordinal value as an int type, and wants to initialize an enum data member, he really has no programmatic idea if the value represents a valid ordinal. He simply tries to set it, and hope for the best (handling an exception if the assignment goes sideways on him). This method allows the programmer to make the same attempt, but with controlled results and thereby avoiding the inevitable exception generated when an invalid ordinal value is used. Usage goes something like this:
enum SomeEnum { Zero=0, Five=5, Six=6, Eight=8 };
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = IntToEnum(5, SomeEnum.Zero);// this will result in SomeEnum.Zero because the value (4) isn't a valid ordinal in the enumerator
value = IntToEnum(4, SomeEnum.Zero);.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001Nice. but, personally, i would replace the default parameter with a delegate.
-
Nice. but, personally, i would replace the default parameter with a delegate.
But why? The whole purpose of the default parameter is to force the method to return a valid ordinal instead of throwing an exception. Making it a take a delegate would, IMHO, add unnecessary obfuscation and maintenance issues.
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
Oh, right, this is a method, not a class; I usually write a generic class and cache the Type.
I am interested in the caching concept... Can you give us a small sample on how its implemented. Do you write two blocks of code, like a singleton - where you save a reference to the type and return it every other time... I am not entirely sure how its done... please share :^)
-
I am interested in the caching concept... Can you give us a small sample on how its implemented. Do you write two blocks of code, like a singleton - where you save a reference to the type and return it every other time... I am not entirely sure how its done... please share :^)
-
But why? The whole purpose of the default parameter is to force the method to return a valid ordinal instead of throwing an exception. Making it a take a delegate would, IMHO, add unnecessary obfuscation and maintenance issues.
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001John Simmons / outlaw programmer wrote:
return a valid ordinal
Which you can't actually guarantee/enforce...
-
In the spirit of the new charter of this forum - "wicked code" - I see this as wicked code... I started programming long before many of the rest of you. Over the years, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy regarding ensuring that data is valid before trying to use it. One of the problems I encountered was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually values - either modified by the user, or incorrectly set or interpreted by the programmer. So I came up with this method that I have include i pretty much every program I write:
public static T IntToEnum<T>(int value, T defaultValue) { T enumValue = (Enum.IsDefined(typeof(T), value)) ? (T)(object)value : defaultValue; return enumValue; }
The purpose of the method is to allow the programmer to initialize a data member of a specified enumerator type to a value contained in the ordinal list. The problem this method addresses is that if the programmer retrieves an enum ordinal value as an int type, and wants to initialize an enum data member, he really has no programmatic idea if the value represents a valid ordinal. He simply tries to set it, and hope for the best (handling an exception if the assignment goes sideways on him). This method allows the programmer to make the same attempt, but with controlled results and thereby avoiding the inevitable exception generated when an invalid ordinal value is used. Usage goes something like this:
enum SomeEnum { Zero=0, Five=5, Six=6, Eight=8 };
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = IntToEnum(5, SomeEnum.Zero);// this will result in SomeEnum.Zero because the value (4) isn't a valid ordinal in the enumerator
value = IntToEnum(4, SomeEnum.Zero);.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001Nice View of the LEO. My First Machine (beyound the accounting machines) was the Wrirlwind I per 1960. My First real Job was on it's child The Mighty AN/FSQ-7 (Sage) Then its child the AN/FSQ-32A The only computer that had an official certified plumber (it was water cooled) on the IBM maintenance roster. Calling them in on the weekends was a trial. They would sihg songs from the IBM Song Book. Ugh! Yes the IBM Song Book - I still have a copy. If you want to see it Google for it. :) :)
-
John Simmons / outlaw programmer wrote:
return a valid ordinal
Which you can't actually guarantee/enforce...
How do you figure? If you pass in a default parameter of a given
enum
type (in our case,SomeEnum.Zero
), then the ordinal has to exist in order to even pass a valid parameter (otherwise, the code wouldn't even compile)..45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
Nice. but, personally, i would replace the default parameter with a delegate.
Just so you know, I didn't 1-vote your message...
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
How do you figure? If you pass in a default parameter of a given
enum
type (in our case,SomeEnum.Zero
), then the ordinal has to exist in order to even pass a valid parameter (otherwise, the code wouldn't even compile)..45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001I could still send in default(T) or any other value. You could check it, but what will you do if the value isn't that of one of the members? Your code has to work for bit-mapped enumerations too doesn't it?
-
I could still send in default(T) or any other value. You could check it, but what will you do if the value isn't that of one of the members? Your code has to work for bit-mapped enumerations too doesn't it?
At some point, you have to rely on the programmer to know wtf he's doing. :) The name of the method kinda gives away its intended use.
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001modified on Saturday, November 21, 2009 9:22 AM
-
In the spirit of the new charter of this forum - "wicked code" - I see this as wicked code... I started programming long before many of the rest of you. Over the years, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy regarding ensuring that data is valid before trying to use it. One of the problems I encountered was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually values - either modified by the user, or incorrectly set or interpreted by the programmer. So I came up with this method that I have include i pretty much every program I write:
public static T IntToEnum<T>(int value, T defaultValue) { T enumValue = (Enum.IsDefined(typeof(T), value)) ? (T)(object)value : defaultValue; return enumValue; }
The purpose of the method is to allow the programmer to initialize a data member of a specified enumerator type to a value contained in the ordinal list. The problem this method addresses is that if the programmer retrieves an enum ordinal value as an int type, and wants to initialize an enum data member, he really has no programmatic idea if the value represents a valid ordinal. He simply tries to set it, and hope for the best (handling an exception if the assignment goes sideways on him). This method allows the programmer to make the same attempt, but with controlled results and thereby avoiding the inevitable exception generated when an invalid ordinal value is used. Usage goes something like this:
enum SomeEnum { Zero=0, Five=5, Six=6, Eight=8 };
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = IntToEnum(5, SomeEnum.Zero);// this will result in SomeEnum.Zero because the value (4) isn't a valid ordinal in the enumerator
value = IntToEnum(4, SomeEnum.Zero);.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001Have you got that code handy in VB.Net? It might come in handy for you in the next few months. :) Tee hee hee.
-
Have you got that code handy in VB.Net? It might come in handy for you in the next few months. :) Tee hee hee.
That's okay - kick a guy when he's down... Do they even have enumerators in VB?
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001 -
That's okay - kick a guy when he's down... Do they even have enumerators in VB?
.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001John Simmons / outlaw programmer wrote:
Do they even have enumerators in VB?
Euhm yes ;P
John Simmons / outlaw programmer wrote:
That's okay - kick a guy when he's down...
Don't worry after a couple years you don't even feel the kicks anymore :sigh: ;P
-
In the spirit of the new charter of this forum - "wicked code" - I see this as wicked code... I started programming long before many of the rest of you. Over the years, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy regarding ensuring that data is valid before trying to use it. One of the problems I encountered was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually values - either modified by the user, or incorrectly set or interpreted by the programmer. So I came up with this method that I have include i pretty much every program I write:
public static T IntToEnum<T>(int value, T defaultValue) { T enumValue = (Enum.IsDefined(typeof(T), value)) ? (T)(object)value : defaultValue; return enumValue; }
The purpose of the method is to allow the programmer to initialize a data member of a specified enumerator type to a value contained in the ordinal list. The problem this method addresses is that if the programmer retrieves an enum ordinal value as an int type, and wants to initialize an enum data member, he really has no programmatic idea if the value represents a valid ordinal. He simply tries to set it, and hope for the best (handling an exception if the assignment goes sideways on him). This method allows the programmer to make the same attempt, but with controlled results and thereby avoiding the inevitable exception generated when an invalid ordinal value is used. Usage goes something like this:
enum SomeEnum { Zero=0, Five=5, Six=6, Eight=8 };
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = IntToEnum(5, SomeEnum.Zero);// this will result in SomeEnum.Zero because the value (4) isn't a valid ordinal in the enumerator
value = IntToEnum(4, SomeEnum.Zero);.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001I think I would prefer this
public static bool TryGetEnumValue<T>(object value, out T enumValue)
{
bool defined = Enum.IsDefined(typeof(T), value);
enumValue = (defined ? (T)value : default(T));
return defined;
}with usage
SomeEnum v;
if (!TryGetEnumValue(4, out v))
throw new ...
else
...The advantage is that this always tells you if the value is defined or not. With the original you'd get the value passed as "defaultValue" if the value tested is the default value OR if the value tested doesn't exist. Most of the time that doesn't really make sense - if the tested value is an argument from a caller for instance, the caller's intention might have been something quite different from using whatever enum member you've designated as the default.
modified on Tuesday, December 1, 2009 4:03 AM
-
In the spirit of the new charter of this forum - "wicked code" - I see this as wicked code... I started programming long before many of the rest of you. Over the years, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy regarding ensuring that data is valid before trying to use it. One of the problems I encountered was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually values - either modified by the user, or incorrectly set or interpreted by the programmer. So I came up with this method that I have include i pretty much every program I write:
public static T IntToEnum<T>(int value, T defaultValue) { T enumValue = (Enum.IsDefined(typeof(T), value)) ? (T)(object)value : defaultValue; return enumValue; }
The purpose of the method is to allow the programmer to initialize a data member of a specified enumerator type to a value contained in the ordinal list. The problem this method addresses is that if the programmer retrieves an enum ordinal value as an int type, and wants to initialize an enum data member, he really has no programmatic idea if the value represents a valid ordinal. He simply tries to set it, and hope for the best (handling an exception if the assignment goes sideways on him). This method allows the programmer to make the same attempt, but with controlled results and thereby avoiding the inevitable exception generated when an invalid ordinal value is used. Usage goes something like this:
enum SomeEnum { Zero=0, Five=5, Six=6, Eight=8 };
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = IntToEnum(5, SomeEnum.Zero);// this will result in SomeEnum.Zero because the value (4) isn't a valid ordinal in the enumerator
value = IntToEnum(4, SomeEnum.Zero);.45 ACP - because shooting twice is just silly
-----
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001Why all the fuss about "starting programming a long time ago before the many of the rest of us"? I've been programming for 2 years now, and I wrote the folowing code snippit about one year ago:
public static bool TryParseEnum<TEnum>(int value, out TEnum result) { result = default(TEnum); var type = typeof (TEnum); if (!type.IsEnum) return false; try { result = (TEnum) Enum.ToObject(type, value); return true; } catch { return false; } } public static bool TryParseEnum<TEnum>(string value, out TEnum result) { result = default(TEnum); var type = typeof(TEnum); if (!type.IsEnum) return false; value = value.ToUpperInvariant(); var names = Enum.GetNames(type); // Enum.IsDefined() is only available as case sensitive foreach (var name in names) { if (name.ToUpperInvariant() != value) continue; result = (TEnum)Enum.Parse(type, value, true); return true; } return false; }
Advantages of this code: - you know if parsing succeeded (while you can't know when returning default values) - case insensitive
modified on Thursday, December 3, 2009 3:13 PM
-
Why all the fuss about "starting programming a long time ago before the many of the rest of us"? I've been programming for 2 years now, and I wrote the folowing code snippit about one year ago:
public static bool TryParseEnum<TEnum>(int value, out TEnum result) { result = default(TEnum); var type = typeof (TEnum); if (!type.IsEnum) return false; try { result = (TEnum) Enum.ToObject(type, value); return true; } catch { return false; } } public static bool TryParseEnum<TEnum>(string value, out TEnum result) { result = default(TEnum); var type = typeof(TEnum); if (!type.IsEnum) return false; value = value.ToUpperInvariant(); var names = Enum.GetNames(type); // Enum.IsDefined() is only available as case sensitive foreach (var name in names) { if (name.ToUpperInvariant() != value) continue; result = (TEnum)Enum.Parse(type, value, true); return true; } return false; }
Advantages of this code: - you know if parsing succeeded (while you can't know when returning default values) - case insensitive
modified on Thursday, December 3, 2009 3:13 PM
That seems like a real good idea. Of course, being a programmer, I immediately try to "perfect" it. My long winded code ends up looking like this. (i wish i could add it as a static method to the Enum class)... i'm also playing with delegates just so that i can play with delegates...
public static class EnumExt {
public static bool TryParse<T>(object value, out T outputEnum) {
if (Enum.IsDefined(typeof(T), value)) {
outputEnum = (T)value;
return true;
} else {
outputEnum = default(T);
return false;
}
}
public static bool TryParse<T>(string value, out T outputEnum) {
string find = Array.Find<string>(Enum.GetNames(typeof(T)),
delegate(string s) { return String.Compare(s, value, true) == 0; });
if (find != null) {
outputEnum = (T)Enum.Parse(typeof(T), find);
return true;
} else {
outputEnum = default(T);
return false;
}
}
}MyEnum example;
if (EnumExt.TryParse<MyEnum>(1, out example)) {
//do stuff
} else {
//do other stuff
}