关于泛型的两个简单问题。函数A(异常ex)与函数B <T>(T ex)相同,其中T:异常?
以下两个函数定义是否相同?
FunctionA(Exception ex);
FunctionB<T>(T ex) where T : Exception;
通用实现(FunctionB)对正常实现(FunctionA)有优势吗?
关于泛型的两个简单问题。函数A(异常ex)与函数B <T>(T ex)相同,其中T:异常?
以下两个函数定义是否相同?
FunctionA(Exception ex);
FunctionB<T>(T ex) where T : Exception;
通用实现(FunctionB)对正常实现(FunctionA)有优势吗?
以下是有效的相同(结果):
catch (Exception e)
{
FunctionA(e);
FunctionB(e);
}
但是,如果你做到这一点是不一样的:
catch (ApplicationException e)
{
FunctionB(e);
}
catch (Exception e)
{
FunctionA(e);
}
这是因为FunctionB得到在编译时输入到ApplicationException的,那么对FunctionA的调用将始终将该参数向下转换为Exception。根据你对FunctionB的实现,这可能并不重要,但有些情况下它可以有所作为。我会说,作为一个经验法则,如果你的方法实现不需要泛型实现,那就不要使用它。
下面是它何时会的一些实例:
public T AddSomeContextToThisException<T>(T ex) where T : Exception
{
ex.Data.Add("Some key", "Some context message");
return ex;
}
public T ThisIsABadIdeaForExceptionsButMaybeAGoodIdeaForOtherTypes<T>(T ex) where T : Exception, new()
{
// do something with ex
return new T();
}
下面的示例需要上下文一些额外的代码,所以看到它下面的代码:
private readonly Bar bar = new Bar();
public void HandExceptionOffToSomethingThatNeedsToBeStronglyTyped<T>(T ex) where T : Exception
{
ICollection<T> exceptions = bar.GetCollectionOfExceptions<T>();
exceptions.Add(ex);
// do other stuff
}
public class Bar
{
// value is object, because .net doesn't have covariance yet
private Dictionary<Type, object> listsOfExceptions = new Dictionary<Type, object>();
public ICollection<T> GetCollectionOfExceptions<T>()
{
if (!listsOfExceptions.ContainsKey(typeof(T)))
{
listsOfExceptions.Add(typeof(T), new List<T>());
}
return listsOfExceptions[typeof(T)] as List<T>;
}
}
里面的功能外,还有没有区别。差异来自外部。如果使用通用函数,则可以将相同类型的例外返回给调用代码而不是基地址Exception
。大多数情况下,这是一个有争议的问题。
没有太多的是FunctionB拥有泛函的优势。但是,两者之间有明显的区别。
使用FunctionA,您可以将从(或是)Exception派生的任何类型传递给该函数。
使用FunctionB,您可以将从T派生的任何类型(必须派生自或作为Exception)传递给该函数。
这意味着根据T的类型,您将拥有一个更专用的参数,它将限制可以传递给它的类型,因为该参数将被输入为T,而不是Exception。
现在如果T是一个异常,那么它没关系,功能是一样的。但是,如果T是InvalidOperationException,那么只允许InvalidOperationException(以及从它派生的类)的实例。
这通常是你想要的,当你想确保一个类型的专业化而不必诉诸不提供你需要的专业化水平的基类。
如果ApplicationException是Exception的子类,它们是不是仍然是相同的呢?尝试/捕捉块我明白;然而,更关心的是两者之间是否有任何差异或好处。 – JamesEggers 2009-04-07 19:42:16
如果您在执行过程中看不到效益,那么没有任何好处,而且几乎没有什么区别。请参阅@塞缪尔的回答,以及我在某些情况下对它的评论。 – 2009-04-07 19:44:53