Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

c# - Why does Enum.Parse create undefined entries?

class Program
{
    static void Main(string[] args)
    {
        string value = "12345";
        Type enumType = typeof(Fruits);
        Fruits fruit = Fruits.Apple;
        try
        {
            fruit = (Fruits) Enum.Parse(enumType, value);
        }
        catch (ArgumentException)
        {
            Console.WriteLine(String.Format("{0} is no healthy food.", value));
        }
        Console.WriteLine(String.Format("You should eat at least one {0} per day.", fruit));
        Console.ReadKey();
    }

    public enum Fruits
    {
        Apple,
        Banana,
        Orange
    }
}

If you execute the code above the result shows:

You should eat at least one 12345 per day.

I really expected an ArgumentException to be thrown if a unknown name (string) is passed. Taking a close look at the Enum.Parse definition reveals:

Summary:
Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.

Exceptions:
ArgumentException: enumType is not an Enum. -or- value is either an empty string or only contains white space. -or- value is a name, but not one of the named constants defined for the enumeration.

I.e. if a string representation of an integer is passed, a new enum value is created and now exception is thrown by design. Does this make sense?

At least I now know to call Enum.IsDefined(enumType, value) prior to Enum.Parse()

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The "named constant" is the textual representation of an Enum's value, not the number that you've assigned to it.

If you change:

string value = "12345";

To:

string value = "Cake";

You'll see the error you're expecting, because "value is a name, but not one of the named constants defined for the enumeration.". In this instance the value you're passing in is a name, "Cake", but not one in the enumeration.

Think of Enum.Parse(enumType, value); doing the following:

  1. If value is a null reference, throw an ArgumentNullException
  2. Is the value in value one of the named constants in the enumeration in enumType. If yes, return that value from the enumeration and stop.
  3. Is the value in value directly convertible to the underlying type (in this instance Int32), if yes, return that value and stop (even if there's no named constant for that value).
  4. Is the value in value directly convertible to the underlying type, but outside of the range of the underlying type? e.g. the value is a string containing a number one greater than MAXINT. If yes, throw an OverflowException.
  5. Is the value not castable to the underlying type? If yes, throw an ArgumentException.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...