C# 如何使用泛型在基类的方法中指定out参数的类型?

C# 如何使用泛型在基类的方法中指定out参数的类型?,c#,generics,exception-handling,enterprise-library,C#,Generics,Exception Handling,Enterprise Library,我正在将ExceptionManager包装在Microsoft的企业库的异常处理块中,我希望允许包装的使用者指定允许包装的实例化器重新调用的异常类型。像这样: public class MyExceptionManager<T> : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionManager where T: MyCustomException { ... public void

我正在将ExceptionManager包装在Microsoft的企业库的异常处理块中,我希望允许包装的使用者指定允许包装的实例化器重新调用的异常类型。像这样:

public class MyExceptionManager<T> : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionManager where T: MyCustomException
{
    ...
    public void LogWrapAndRethrow(Exception e, T t)
    {
        base.HandleException( e, "MyPolicyName", out t);
    }
...
}
它不是泛型类

不幸的是,我一直在为。。。具有一些无效参数,即使T被约束为从Exception继承的类型。如果我手动创建并分配一个异常变量,它将作为一个输出参数


我做错了什么?

用于out参数的参数必须与声明的参数类型完全匹配。由于HandleException有第三个参数OutExceptionToThrow,所以目前无法使用

鉴于不需要异常从方法中返回,因此最简单的方法是将方法编写为:

public void LogWrapAndRethrow(Exception e, T t)
{
    Exception tmp = t;
    base.HandleException( e, "MyPolicyName", out tmp);
}

现在,您正在使用类型为Exception的参数调用该方法,这没关系。

用于out参数的参数必须与声明的参数类型完全匹配。由于HandleException有第三个参数OutExceptionToThrow,所以目前无法使用

鉴于不需要异常从方法中返回,因此最简单的方法是将方法编写为:

public void LogWrapAndRethrow(Exception e, T t)
{
    Exception tmp = t;
    base.HandleException( e, "MyPolicyName", out tmp);
}

现在,您正在使用类型为Exception的参数调用该方法,这样就可以了。

base.HandleException也是泛型的吗?@Selman22否,添加了一些内容来解释您试图执行不允许的操作。基类不能在out参数中返回t,因为该参数被声明为异常。您的T可能是MyCustomExceptionClass,但您不能保证该方法不会从编译器的角度,而不是从方法契约的角度,尝试将ArgumentNullException分配给参数。base.HandleException也是泛型的吗?@Selman22否,添加了内容来解释您尝试执行的是不允许的操作。基类不能在out参数中返回t,因为该参数被声明为异常。您的T可能是MyCustomExceptionClass,但您不能保证该方法不会从编译器的角度,而不是从方法契约的角度,尝试将ArgumentNullException分配给参数。如果抛出T;,会发生什么;?它会被对基方法的调用所改变吗?@chrismcall,这取决于基方法的契约。有记录吗?@chrismcall-See。只有当HandleException返回true时,才应该重新调用,并且应该抛出t??e、 有效地。还要注意的是,通过将此逻辑放在其自己的方法中,您正在丢失潜在的有价值的堆栈跟踪信息。感谢@phoog,我将测试堆栈跟踪的任何丢失,并采取适当的措施。如果我抛出t;,会发生什么;?它会被对基方法的调用所改变吗?@chrismcall,这取决于基方法的契约。有记录吗?@chrismcall-See。只有当HandleException返回true时,才应该重新调用,并且应该抛出t??e、 有效地。还要注意的是,通过将此逻辑放在其自己的方法中,您将丢失可能有价值的堆栈跟踪信息。感谢@phoog,我将测试stacktrace的任何丢失,并采取适当的措施。
public void LogWrapAndRethrow(Exception e, T t)
{
    Exception tmp = t;
    base.HandleException( e, "MyPolicyName", out tmp);
}