Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / Visual Basic
Tip/Trick

Setting Enumerators From Questionable Data Sources (for C# and VB)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
9 Jul 2011CPOL2 min read 17.1K   6   2
Avoid exceptions when setting enumerators from unknown/untrusted sources.

Introduction


This was originally posted in the Wicked Code forum, but that was before Tips/Tricks came into vogue, so I moved it here.

I started programming almost 30 years ago. Over that time, I've grown to have a huge distrust of not only users and their antics, but also other programmers and their seeming apathy toward ensuring that data is valid before trying to use it.

Why We're Here (For the C# Devs)


One of the problems I encountered with .Net was storing and retrieving enumerator values in data sources, and preparing the code to gracefully handle manually converting values - either modified by the user, incorrectly set or interpreted by the programmer, or refactored without appropriate notice to those programmers. To save myself a lot of time, I came up with a couple of methods that I include in 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 hopes 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, 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);

Fine, right? But what if the enum value was stored as a string? I have an answer for you, and it looks a lot like the first one.
public static T StringToEnum<T>(string value, T defaultValue)
{
    T enumValue = (Enum.IsDefined(typeof(T), value)) ? 
                   (T)Enum.Parse(typeof(T), value) : 
                   defaultValue;
    return enumValue;
}

Given the enum defined in the first usage example, you would do something like this:
// this will result in the correct expected value - SomeEnum.Five
SomeEnum value = StringToEnum("5", SomeEnum.Zero);

// this will result in SomeEnum.Zero because the value (4) isn't a 
// valid ordinal in the enumerator
value = StringToEnum("4", SomeEnum.Zero);

And For The VB.Net Devs


Recently, I held a job that forced me to code in VB.Net. For all the VB.Net people out there, here's the same code converted to your preferred/forced language:
Public Shared Function IntToEnum(Of T)(value As Integer, defaultValue As T) As T
    Dim enumValue As T = If(([Enum].IsDefined(GetType(T), value)), _
                             DirectCast(DirectCast(value, Object), T), _
                             defaultValue)
    Return enumValue
End Function

Public Shared Function StringToEnum(Of T)(value As String, defaultValue As T) As T
    Dim enumValue As T = If(([Enum].IsDefined(GetType(T), value)), _
                            DirectCast([Enum].Parse(GetType(T), value), T), _
                            defaultValue)
    Return enumValue
End Function

Closing Comment


For every approach to a given problem, there are many varied implementations that can be coded. Some of you may prefer the TryParse/handle error method to implementing this particular code, and that's fine. That's what's so cool about coding. You can hit the same problem from wildly different angles and still be right.

Edits



09 Jul 2011 = Fixed a pointy bracket display problem in a code snippet, as well as a couple of misspellings.

05 May 2010 - The string version is different in Silverlight 3. You need to add a third parameter to the Parse method call that indicates whether or not you want to honor case sensitivity.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
GeneralHi John, I'm testing the new comment facilities. Can you rep... Pin
Luc Pattyn4-May-10 4:01
sitebuilderLuc Pattyn4-May-10 4:01 
GeneralTypos Pin
AspDotNetDev25-May-10 14:09
protectorAspDotNetDev25-May-10 14:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.