我有一个方法可以检查传入的异常并返回一个bool值。
目前我的实施就像这样
private bool ExceptionShouldNotify(Exception e)
{
return
e is FirstCustomException ||
e is SecondCustomException ||
e is ThirdCustomException ||
e is FourthCustomException ||
e is FifthCustomException ||
e is SixthCustomException ||
e is SeventhCustomException;
}
然而,使用字典查找而不是几个OR
语句和is
检查会更好地提高性能吗?
这样的事情:
private bool ExceptionShouldNotify(Exception e)
{
var dict = new Dictionary<String, int> {
{ "FirstCustomException", 1 },
{ "SecondCustomException", 1 },
{ "ThirdCustomException", 1 },
{ "FourthCustomException", 1 },
{ "FifthCustomException", 1 },
{ "SixthCustomException", 1 },
{ "SeventhCustomException", 1 }
};
return dict.ContainsKey(e.GetType().Name);
}
答案 0 :(得分:5)
硬编码(第一个解决方案)是一个不好的做法,这就是为什么我投票支持字典(第二个解决方案),但我建议不同的实现:
// HashSet - you don't use Value in the Dictionary, but Key
// Type - we compare types, not their names
private static HashSet<Type> s_ExceptionsToNotify = new HashSet<Type>() {
typeof(FirstCustomException),
typeof(SecondCustomException),
...
};
// static: you don't use "this" in the method
private static bool ExceptionShouldNotify(Exception e) {
return s_ExceptionsToNotify.Contains(e.GetType());
}
捕获到异常(包括堆栈跟踪),您已经有了很大的开销;这就是为什么性能(7个简单的比较与计算哈希)不是上下文中的主要问题
答案 1 :(得分:1)
如果要检查相当多的异常类型,查找字典是有意义的。但是,我会避免在此上下文中使用strings
。您可以依赖Type
类型:
var dict = new Dictionary<Type, int>()
{
[typeof(FirstCustomerException)] = 1,
[typeof(SecondCustomException)] = 1,
...
};
然后,您可以按例外对象的类型查找字典:
try
{
...
}
catch (Exception ex)
{
int mapTo;
if (dict.TryGetValue(ex.GetType(), out mapTo))
{
// Use mapTo value here
}
}
您甚至可以使用C#6中称为异常过滤器的最新功能来捕获字典中存在的异常:
try
{
...
}
catch (Exception ex) when (dict.ContainsKey(ex.GetType())
{
int mapTo = dict[ex.GetType()];
// Use mapTo value here
}
这个实现稍慢一点,因为你必须两次调用GetType
,并且还要执行两次字典映射。但它带来的好处是它保证你的catch块确实会处理异常,因为它只会输入映射中的异常而不是任何其他类型的异常。
答案 2 :(得分:0)
是的,应该。根据{{1}}文档,Dictionary
方法接近O(1),而Contains
语句链为O(N)。
https://msdn.microsoft.com/en-us/library/kw5aaea4(v=vs.110).aspx#Remarks
如果您使用or
,我会更改密钥以使用the Dictionary
来更有效地防止打字错误。