TryGet方法风格的最佳实践

时间:2016-05-31 13:06:19

标签: c# methods exception-handling

我有一个枚举方法,如下所示:

public static TEnum GetEnumByStringValue<TEnum>(string value) where TEnum : struct, IConvertible, IComparable, IFormattable
{
  if(!typeof(TEnum).IsEnum)
  {
    throw new ArgumentException("TEnum must be an enumerated type.");
  }

  Type type = typeof(TEnum);
  FieldInfo[] fieldInfos = type.GetFields();
  foreach (FieldInfo fieldInfo in fieldInfos)
  {
    StringValue[] stringValues = fieldInfo.GetCustomAttributes(typeof(StringValue), false) as StringValue[];
    if (stringValues != null)
    {
      foreach (StringValue stringValue in stringValues)
      {
        if (stringValue.Value.Equals(value))
        {
          return (TEnum)Enum.Parse(typeof(TEnum), fieldInfo.Name);
        }
      }
    }

  }
  throw new ArgumentOutOfRangeException("value", "Value was not found in enum's string values.");
}

我想实现一个TryGetEnumByStringValue,它返回true或false,而不是抛出类似于int.Parseint.TryParse概念的异常。我看到它的方式,在我的新方法中,我可以调用我的另一个,捕获异常(如果有的话)并相应地返回,或者我可以重构现有的返回bool并再次在我的新方法中调用现有的并在返回false时抛出异常。

如果我选择选项2,我会丢失确切的异常详细信息,如果我选择选项1,则仍会抛出异常(我总是被教导异常很慢)。

我还可以重构现有的一个来取一个bool来指示是否抛出异常,但这并不适合我。

我是否因为这种方法风格或模式而错过了一颗智慧之珠?

1 个答案:

答案 0 :(得分:0)

如果你已经拥有抛出的方法,那么很容易使用Try...变体使用......太惊讶了! try/catch

public bool TryReturnSomething(..., out SomeType result) // ... - parameters
{
    try
    {
        result = ReturnSomething();
        return true;
    }
    catch(SomeException1 e) { } // catch all expected exception types
    catch(SomeException2 e) { }

    return false;
}

调查sources你会发现miscrosoft确实使用了一种模式。它们具有使用验证的参数调用的内部方法。验证由Try...和普通变体单独完成。参见例如double.Parse()double.TryParse(),首先验证时为throw,其他为false。

因此,如果您可以创建一个由两个变体调用的私有方法。此方法不应验证任何内容(可能会出现异常)并在公共变体中调用此方法,这两种方法都验证参数(Try..返回false和其他抛出)。