我有一个枚举方法,如下所示:
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.Parse
和int.TryParse
概念的异常。我看到它的方式,在我的新方法中,我可以调用我的另一个,捕获异常(如果有的话)并相应地返回,或者我可以重构现有的返回bool
并再次在我的新方法中调用现有的并在返回false时抛出异常。
如果我选择选项2,我会丢失确切的异常详细信息,如果我选择选项1,则仍会抛出异常(我总是被教导异常很慢)。
我还可以重构现有的一个来取一个bool
来指示是否抛出异常,但这并不适合我。
我是否因为这种方法风格或模式而错过了一颗智慧之珠?
答案 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和其他抛出)。