0

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?

Bob Horn
  • 33,387
  • 34
  • 113
  • 219

2 Answers2

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • About making the method generic, I had this conversation on another post from yesterday: http://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. – Bob Horn May 22 '14 at 13:45
  • @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` instead of `List`). It's unfortunate that `Enum.GetValues` itself returns boxed values, but Unconstrained Melody doesn't :) – Jon Skeet May 22 '14 at 13:47
  • 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: https://dotnetfiddle.net/JhToL2. And thanks for the Unconstrained Melody link. I'll check that out. – Bob Horn May 22 '14 at 14:01
  • @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. – Jon Skeet May 22 '14 at 14:03
  • 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. – Bob Horn May 22 '14 at 14:10
  • @BobHorn: That *is* picking a value - the 0 value, basically. It's still an arbitrary value from `SomeEnum`, where the value isn't important. The generic extension method doesn't need to make it available to all types - that's what Unconstrained Melody is about (constraining generic methods to enums or delegates) - but I don't think this should be an extension method at all. – Jon Skeet May 22 '14 at 14:12
  • LOL. Not only have you proven your point, and helped me understand the best way to go (which is honorable enough in its own right), but you've even written a library to handle this specific issue. What's the matter with you? ;) – Bob Horn May 22 '14 at 14:16
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());        
}
Mijael
  • 121
  • 1
  • 7