Click here to Skip to main content
14,693,631 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Could it ever be necessary, in a class method with an enum as a parameter, to catch an argument out of range event?

Such as InvalidEnumArgumentException or ArgumentOutOfRangeException?

public virtual void ToGrey(RGBGreyScaleMethod method)
{
    Switch (method) {
        case RGBGreyScaleMethod.Average:
            this.ByAverage();
	    break;
        case RGBGreyScaleMethod.BlueChannel:
	    this.FromBlue();
	    break;
        case RGBGreyScaleMethod.Brightness:
            this.FromBrightness();
            break;
        case RGBGreyScaleMethod.Decompose:
            this.Decompose();
            break;
        case RGBGreyScaleMethod.Desaturate:
            this.Desaturate();
            break;
        case RGBGreyScaleMethod.GreenChannel:
            this.FromGreen();
            break;
        case RGBGreyScaleMethod.RedChannel:
            this.FromRed();
            break;
        default:
            //ToDo: Clean this up and add XML comments
            //ToDo: Consider InvalidEnumArgumentException as alternative
            Throw new ArgumentOutOfRangeException("The supplied RGBGreyScaleMethod was not recognised");
    }
}

public enum RGBGreyScaleMethod
{
    Desaturate
    Decompose
    Brightness
    Average
    RedChannel
    GreenChannel
    BlueChannel
}


Or would such a think be automagically handled by the compiler, run time environment? I.e. would catching the error in such a case be superfluous?

Thanks,
M
Posted
Comments
idenizeni 18-Aug-13 17:22pm
   
Using your example code; if an item was added to the RgbGreScaleMethodType enum but the ToGrey routine wasn't updated then you may want the default case to alert you.

Of course nothing would throw exception or otherwise indicate invalid enumeration value unless you do it by yourself.

However, you should think about it: do you really need a guard against such cases? Indeed, how such cases can appear? For example, you can develop some code which calculates some integer value, and then type-cast it to your enumeration type, to call your method. Naturally, this is the risk of getting the value out of the valid set. A resolution? Don't do evil (in this case, type cast from integer), and you won't have a problem.

Another case is: the values comes from the stream from some other process, via network. It is possible that the sending process is running on some other machine, where you use obsolete or newer library, an assembly where your enumeration type is defined. Then again, if the enumeration type is different on different sides of the network application, the value out of valid set of enumeration values (for one of the sides/version) is quite possible. A resolution? Don't be sloppy, and you won't have this problem. How? Don't work with incompatible version. Create a mechanism of incremental version update, a mechanism checking up all versions of all assemblies (through reflection) and sending this version information through network for rigorous check-up.

And finally, the whole idea of your long case statement comparing value with separate enumeration members is not a very good idea. Please see my articles explaining some more advanced and less meticulous and less error-prone techniques:
Enumeration Types do not Enumerate! Working around .NET and Language Limitations[^],
Dynamic Method Dispatcher[^].

—SA
   
v2
Comments
Mike-MadBadger 19-Aug-13 2:29am
   
Thanks, I will keep this for futur e reference. In this case however it feels a bit like overkill since the chances of me inventing a significantly increased number of ways of converting colour to greyscale are limited (and hence changing the enumeration).

The switch remains ugly but 'more readable' (to me) than adding the code from your two articles.
   
I don't mind, just thought it would be good to know. Pay attention that in my article on enumerations I first overview the techniques based on available language features, without adding my classes.

My main point is safe programming which won't require protection against enumeration values out of the valid set; I hope you got it.

Good luck, call again.
—SA
Mike-MadBadger 27-Aug-13 16:23pm
   
Struggled a bit to understand your articles, they are, at least as yet, a bit ahead of me - hopefully I'll get there sooner or later.
I did however find this: http://blogs.microsoft.co.il/blogs/gilf/archive/2009/11/22/applying-strategy-pattern-instead-of-using-switch-statements.aspx
I found it be a usefully simpler explanation for my level.
Sergey Alexandrovich Kryukov 27-Aug-13 21:53pm
   
Great.
Good luck, call again.
—SA
Joezer BH 10-Sep-13 3:30am
   
5ed!
Sergey Alexandrovich Kryukov 10-Sep-13 10:38am
   
Thank you.
—SA
No, it wouldn't be automatic.
My practice is to include an ArgumentException throw on the default case of an enum based switch statement for the same time your code does - there is no way to catch a "missing value" at compile time, so if I add and option to the enum, I need some way to detect that I have forgotten to update this particular switch out of the however many I have needed.
The only difference between our codes is that my exception includes the unrecognised switch value so that if I log it, I log the missed value as well.

[edit]BL**DY tablet auto correct![/edit]
   
v2
Comments
Mike-MadBadger 19-Aug-13 2:26am
   
Thanks, useful and straightforward. I guess I was wondering if the compiler added the relevant code to handle problems gracefully and informatively if, for example, someone passed in a typecast integer that was out of range. Or if it would throw a largely useless and informative error. The latter case, in my original thinking, would be the only justification for adding my own error..throw code, however...

You're second point is the same as that of RLH68? (his comment on my question). I'd forgotten to think of the error from both directions in either case.

For interest, which error type do you throw?
OriginalGriff 19-Aug-13 3:19am
   
Generally ArgumentException (though I should derive my own, but don't...)
Mike-MadBadger 27-Aug-13 16:27pm
   
Out of interest (sorry for the delay) why custom rather than InvalidEnumArgumentException or ArgumentOutOfRangeException?
I get the idea / benefit of writing your own exceptions, however those two seem pretty well aligned with the problem at hand?
OriginalGriff 28-Aug-13 5:49am
   
It's six of one and half a dozen of the other!
Some people advocate that you should derive an exception type specific to your app from the generic ones, so that they can be trapped separately, and more specifically. Others feel that as long as you aren't throwing
throw new Exception("Big problem!);
It's all right.
I'm kinda in the middle - I throw ArgumentExceptions and so forth, because I haven't really made up my mind yet! I'm not convinced that proliferating exception types is either necessary or a good idea, (particularly since so many people throw the exception away without looking at it, or don't bother to catch anything at all... :sigh:)

Does proliferating exceptions make it more likely that uses will just write
catch (Exception ex)
{
}
Yes, I think it does...

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




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900