简体   繁体   English

TryGet方法风格的最佳实践

[英]Best practice for TryGet method style

I have an method for enums that looks like this: 我有一个枚举方法,如下所示:

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.");
}

I'd like to implement a TryGetEnumByStringValue , that returns true or false instead of throwing an exception similar to the concept of int.Parse and int.TryParse . 我想实现一个TryGetEnumByStringValue ,它返回true或false,而不是抛出类似于int.Parseint.TryParse概念的int.TryParse The way I see it, in my new method I could just call my other one, catch the exceptions (if any) and return accordingly, or I could refactor the existing one to return bool and again in my new method simply call the existing one and throw an exception if it returns false. 我看到它的方式,在我的新方法中,我可以调用我的另一个,捕获异常(如果有的话)并相应地返回,或者我可以重构现有的返回bool并再次在我的新方法中简单地调用现有的如果返回false则抛出异常。

If I go with option 2 I lose exact exception details, and if I go with option 1 the exceptions are still thrown (I've always been taught exceptions are slow). 如果我选择选项2,我会丢失确切的异常详细信息,如果我选择选项1,则仍会抛出异常(我总是被教导异常很慢)。

I could also refactor the existing one to take a bool indicating whether to throw exceptions or not, but that doesn't quite sit right with me. 我还可以重构现有的一个bool指示是否抛出异常,但这并不适合我。

Is there a pearl of wisdom I've missed for this sort of method style or pattern? 对于这种方法风格或模式,我是否错过了一颗智慧之珠?

If you already have method that throws, then it's easy to make Try... variant of it using ... suprise! 如果你已经有抛出的方法,那么很容易使用它来Try...Try...变种!惊喜! try/catch : 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;
}

Looking into sources you will discover that miscrosoft is indeed using kind of pattern . 查看消息来源,您会发现miscrosoft确实使用了一种模式 They have internal method which is called with validated parameters. 它们具有内部方法,该方法使用经过验证的参数调用。 And validation is done individually by Try... and normal variant. 并且通过Try...和普通变体单独完成验证。 See eg double.Parse() and double.TryParse() , first one will throw when validating and other return false. 参见double.Parse()double.TryParse() ,第一个将在验证时throw而其他将返回false。

So if you can create a private method which you call by both variants. 因此,如果您可以创建一个由两个变体调用的私有方法。 This method should not validate anything (may rise exception) and call this method in public variants, which both validate parameters ( Try.. return false and other throws). 此方法不应验证任何内容(可能会引发异常)并在公共变体中调用此方法,这两种方法都验证参数( Try.. return false和其他throws)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM