Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best exception for an invalid generic type argument

I'm currently writing some code for UnconstrainedMelody which has generic methods to do with enums.

Now, I have a static class with a bunch of methods which are only meant to be used with "flags" enums. I can't add this as a constraint... so it's possible that they'll be called with other enum types too. In that case I'd like to throw an exception, but I'm not sure which one to throw.

Just to make this concrete, if I have something like this:

// Returns a value with all bits set by any values public static T GetBitMask<T>() where T : struct, IEnumConstraint {     if (!IsFlags<T>()) // This method doesn't throw     {         throw new ???     }     // Normal work here } 

What's the best exception to throw? ArgumentException sounds logical, but it's a type argument rather than a normal argument, which could easily confuse things. Should I introduce my own TypeArgumentException class? Use InvalidOperationException? NotSupportedException? Anything else?

I'd rather not create my own exception for this unless it's clearly the right thing to do.

like image 210
Jon Skeet Avatar asked Sep 11 '09 18:09

Jon Skeet


People also ask

Which exception is thrown when one of the arguments provided to a method is not valid?

Remarks. ArgumentException is thrown when a method is invoked and at least one of the passed arguments does not meet the parameter specification of the called method. The ParamName property identifies the invalid argument.

What is InvalidOperationException in C#?

InvalidOperationException is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments. Typically, it is thrown when the state of an object cannot support the method call. For example, an InvalidOperationException exception is thrown by methods such as: IEnumerator.


1 Answers

NotSupportedException sounds like it plainly fits, but the documentation clearly states that it should be used for a different purpose. From the MSDN class remarks:

There are methods that are not supported in the base class, with the expectation that these methods will be implemented in the derived classes instead. The derived class might implement only a subset of the methods from the base class, and throw NotSupportedException for the unsupported methods.

Of course, there's a way in which NotSupportedException is obviously good enough, especially given its common-sense meaning. Having said that, I'm not sure if it's just right.

Given the purpose of Unconstrained Melody ...

There are various useful things that can be done with generic methods/classes where there's a type constraint of "T : enum" or "T : delegate" - but unfortunately, those are prohibited in C#.

This utility library works around the prohibitions using ildasm/ilasm ...

... it seems like a new Exception might be in order despite the high burden of proof we justly have to meet before creating custom Exceptions. Something like InvalidTypeParameterException might be useful throughout the library (or maybe not - this is surely an edge case, right?).

Will clients need to be able to distinguish this from BCL Exceptions? When might a client accidentally call this using a vanilla enum? How would you answer the questions posed by the accepted answer to What factors should be taken into consideration when writing a custom exception class?

like image 139
Jeff Sternal Avatar answered Oct 15 '22 21:10

Jeff Sternal