我应该为Enum扩展方法使用ArgumentException还是InvalidEnumArgumentException吗?

时间:2019-04-28 07:56:24

标签: c#

我看到了两者的建议,但想确认这是执行此操作的最佳方法:

public enum MO
{
   Learn = 0,
   Practice = 1,
   Quiz = 2
}

public static partial class Extensions
{
   public static MO ToMode(this string mode)
   {
      switch (mode)
      {
         case "Learn": return MO.Learn;
         case "Practice": return MO.Practice;
         case "Quiz": return MO.Quiz;
         default: throw new InvalidEnumArgumentException("Unhandled value: " + mode.ToString());
      }
    }
}

3 个答案:

答案 0 :(得分:6)

在这种情况下,我将使用.venv.venv/bin/python3.7 states的文档:

  

如果将无效的枚举值传递给方法或设置属性,则会引发此异常。

这不是您在这里所做的。您正在传递字符串,而不是枚举。对.venv/bin/python looks的描述更合适:

  

提供给方法的参数之一无效时引发的异常。

答案 1 :(得分:2)

您根本不应该扔东西。保持纯洁。

   public static (bool, MO) ToMode(this string mode)
   {
      switch (mode)
      {
         case "Learn": return (true, MO.Learn);
         case "Practice": return (true, MO.Practice);
         case "Quiz": return (true, MO.Quiz);
         default: return (false, default);
      }
    }

...让您的呼叫者检查标志并决定要做什么。

其他方法是将MO.Unset选项用作默认的“无法识别”标签。然后,只要输入参数意外,您就只需返回MO.Unset

让您的代码纯净,年轻,绝地。

P.S。最好在enum上使用默认值,即使您不会以我建议的方式使用它也是如此:enum是值类型,因此始终为非null default值;如果您不提供任何一种,很可能会搞砸。

答案 2 :(得分:2)

我倾向于让框架来决定。框架是这样的:

public static partial class Extensions
{
    public static MO ToMode(this string mode) => (MO)Enum.Parse(typeof(MO), mode);
}

现在,如果您传递无效的字符串,则会引发ArgumentException


或者,您可以实施TryParseMode来完全避免异常:

public static partial class Extensions
{
    private static Dictionary<string, MO> _lookup =
        Enum
            .GetNames(typeof(MO))
            .ToDictionary(n => n, n => n.ToMode());

    public static bool TryParseMode(this string mode, out MO value)
    {
        var found = _lookup.ContainsKey(mode);
        value = found ? _lookup[mode] : default(MO);
        return found;
    }

    public static MO ToMode(this string mode) => (MO)Enum.Parse(typeof(MO), mode);
}

您将这样使用:

Console.WriteLine("Learn".TryParseMode(out MO m1));
Console.WriteLine("LearnX".TryParseMode(out MO m2));

...返回:

True
False