tags:

views:

165

answers:

2

Why is this even possible? Is it a bug?

using System;

public class InvalidEnumParse
{
    public enum Number
    {
        One,
        Two,
        Three,
        Four
    }

    public static void Main()
    {
        string input = "761";
        Number number = (Number)Enum.Parse(typeof(Number), input);
        Console.WriteLine(number); //outputs 761
    }
}
+9  A: 

That's just the way enums work in .NET. The enum isn't a restrictive set of values, it's really just a set of names for numbers (and a type to collect those names together) - and I agree that's a pain sometimes.

If you want to test whether a value is really defined in the enum, you can use Enum.IsDefined after parsing it. If you want to do this in a more type-safe manner, you might want to look at my Unconstrained Melody project which contains a bunch of constrained generic methods.

Jon Skeet
Although the designers of the .Net framework advise against using Enum.IsDefined (http://blogs.msdn.com/kcwalina/archive/2004/05/18/134208.aspx)
Davy Landman
Thanks, the Enum.IsDefined solved our problem.I still think it's very confusing behavior, causing hard to track bugs.
Ward Werbrouck
@Davy Landman : what else do you suggest to check if the Enum really has a defined value?
Ward Werbrouck
@Davy: It depends on the scenario. If you're just trying to validate that you've been passed a defined value, it's fine IMO. If you're trying to validate that you've been passed a value that your specific method knows about, then `switch` is a better solution.
Jon Skeet
@Ward Werbrouck, I just wanted to add that you should be aware of the cost of the .IsDefined and that using a switch statement with a default handler might solve your problem (although not for this example).
Davy Landman
@Davy: The cost of IsDefined is precisely why I've got an equivalent (which will hopefully be cheaper, although it's not optimised at the moment) in Unconstrained Melody :)
Jon Skeet
@Jon, never heard of it (until now), looking at it, seems very cool :)
Davy Landman
A: 

If you have a enum with [Flags] attribute, you can have any value combination. For instance:

[Flags]
enum Test
{
    A = 1, 
    B = 2,
    C = 4,
    D = 8
}

You could to do this:

Test sample = (Test)7;
foreach (Test test in Enum.GetValues(typeof(Test)))
{
    Console.WriteLine("Sample does{0} contains {1}",
        (sample & test) == test ? "": " not", test);
}
Rubens Farias
@Rubens: .NET *could* still limit that to any valid combination of bits, of course - it just doesn't.
Jon Skeet
@Jon, what about a `sample++`? It's harder to spot (while I understand that still possible detection)
Rubens Farias
@Rubens: What do you mean? Basically any assignment to an enum field (including compound assignment operators) would have to perform the test.
Jon Skeet
you're right, ty
Rubens Farias