1

I have this extension method for an Enum:

public static List<Enum> Values(this Enum theEnum)
{
    return Enum.GetValues(theEnum.GetType()).Cast<Enum>().ToList();
}

I'm getting a code analysis violation:

CA1062 Validate arguments of public methods
In externally visible method 'EnumExtensions.Values(this Enum)', validate parameter 'theEnum' before using it.

Why is that happening? How can I validate the parameter? I can't check for null because an enum is a non-nullable value type. Is there some other check that is supposed to be occurring here?

1
  • Enum itself is a reference type so you can check for null. Commented May 22, 2014 at 13:37

2 Answers 2

6

I can't check for null because an enum is a non-nullable value type.

Any particular enum is a value type, but Enum itself isn't. (Just like ValueType isn't a value type either... every type derived from ValueType except Enum is a value type.)

In other words, I could write:

Enum foo = null;
var bang = foo.GetValues();

That would compile and then fail at execution time with a NullReferenceException.

Given that you ignore the value except to get its type, I'd actually suggest removing it and either accepting a Type or making it generic in the type of enum you want. But if you want to keep the current signature, you just need:

if (theEnum == null)
{
    throw new ArgumentNullException();
}

You might also want to look at my Unconstrained Melody project which provides a bunch of helper methods for enums, generically constrained to enum types via IL manipulation.

Sign up to request clarification or add additional context in comments.

7 Comments

About making the method generic, I had this conversation on another post from yesterday: stackoverflow.com/q/23794691/279516. It seemed as though each approach had a flaw, and perhaps it was best to just create a static method instead of an extension method. Then I came up with the method I posted in my question, above, and I don't know that that's any worse than the other suggestions. Using a generic extension method meant that all types would have that extension method available to it, and that's not good.
@BobHorn: I think it's worse than the static generic method, because it's accepting a value it doesn't need (and which could be null, as you've seen). Additionally, you end up with a list of boxed values and less compile-time type safety (as you just have List<Enum> instead of List<YourParticularEnum>). It's unfortunate that Enum.GetValues itself returns boxed values, but Unconstrained Melody doesn't :)
In what way is the method accepting a value it doesn't need? Isn't the method using the instance to determine the type? If you look at the output of theEnum.GetType(), you'll see that it's the type of my enum, not Enum itself. This fiddle demonstrates that: dotnetfiddle.net/JhToL2. And thanks for the Unconstrained Melody link. I'll check that out.
@BobHorn: It's only using the type of the value. That's all that it cares about - that could be specified either as a Type or via generics. And I'm quite aware that theEnum.GetType() will give the right type, but that's still no reason to require an actual value, when it doesn't matter which value in the enum you give. I still think the generic approach is much cleaner - the only downside of that is if you ever want to call it when you don't know the type at compile-time, but I don't think that's your situation.
A reason for using it the way it is would be that the method call is more succinct. But, yeah, that's not always a good reason to do something. And the caller doesn't need to explicitly pick a value. It could do new SomeEnum().Values(). And the generic extension method approach would make the method available to all types. Certainly that can't be viewed as better. So maybe the real answer is to use a generic method that's not an extension method. Or use Unconstrained Melody.
|
0

The enum keyword is used to declare an enumeration, a distinct type that consists of a set of named constants called the enumerator list.

It is used just for declare another enums. In any case, the input should be your declaration.

public enum theEnum { 
  enum1,
  enum2
}

public void ShowEnum(theEnum e) 
{
   System.Console.WriteLine(e.GetType());        
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.