TryGet 方法风格的最佳实践

lda*_*dam 5 c# methods exception

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

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.");
}
Run Code Online (Sandbox Code Playgroud)

我想实现一个, 返回 true 或 false,而不是抛出类似于andTryGetEnumByStringValue概念的异常。在我看来,在我的新方法中,我可以调用我的另一个方法,捕获异常(如果有)并相应地返回,或者我可以重构现有的方法以返回,然后在我的新方法中再次简单地调用现有的方法并如果返回 false,则抛出异常。int.Parseint.TryParsebool

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

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

对于这种方法风格或模式,我是否错过了智慧的珍珠?

Sin*_*atr 2

如果您已经有一个抛出异常的方法,那么很容易使用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;
}
Run Code Online (Sandbox Code Playgroud)

查阅资料你会发现微软确实在使用这种模式。它们有一个使用经过验证的参数调用的内部方法。验证是由Try...正常变体单独完成的。参见例如double.Parse()double.TryParse()。第一个将throw返回无效输入,另一个将返回false

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

  • 但请考虑到,通常您会使用 TryGet 模式来解决性能问题,因此您永远不会在此方法中抛出异常,因为这会显着减慢该方法的执行速度。有关详细信息,请参阅此处的 [Microsoft 设计指南](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions-and-performance) - 此处称为 Try-Parse 模式。 (5认同)