通用转换

时间:2013-05-07 07:45:58

标签: c# generics covariance

基本上我正在做的是从Exception转换为GenericFaultException类(下面的代码片段使用C#作为语言。

见以下详细信息

FaultException<T>:FaultException(FaultException derived from exception)

FaultException:Exception

我使用下面的代码行

创建了一个faultExceptionObject
public class ValidationFault: IValidationFault
{
}

FaultException<ValidationFault> faultExceptionObject=new FaultException<ValidationFault>(new ValidationFault())

我有一个错误处理层,它对ValidationFault类一无所知,只知道IValidationFault。

public Exception HandleException(Exception exception, Guid handlingInstanceId)
{    
  FaultException<IValidationFault> genericFaultException = exception as FaultException<IValidationFault>;
   //********genericFaultException is always NULL**********************
   IValidationFault fault = genericFaultException.Detail as IValidationFault;
 }

由于某种原因,该行:

FaultException<IValidationFault> genericFaultException = exception as FaultException<IValidationFault>;  

导致genericFaultException 始终等于null ,但是从QuickWatch我看到Exception的类型为FaultException<ValidationFault>。我该如何从Exception转换为FaultException<IValidationFault>

如果您需要更多信息,请与我们联系。

提前致谢

2 个答案:

答案 0 :(得分:3)

exception as FaultException<IValidationFault>为空的原因是因为FaultException<ValidationFault> a FaultException<IValidationFault>

要使此操作按您的方式工作,必须编写FaultException<T>以使T具有协变性。但你不能在c#中为类做到这一点。你必须使用一个界面。这是一个应该有效的例子:

public interface IFaultException<out T>
{
    T Detail { get; }
}

public class FaultException<T> : Exception, IFaultException<T>
{
    private T _detail;
    public T Detail { get { return _detail; } }
    public FaultException(T detail, string message, Exception innerException)
    : base(message, innerException)
    {
       _detail = detail;
    }
}

使用此类和接口,您可以执行错误处理代码:

IFaultException<IValidationFault> genericFaultException =
    exception as IFaultException<IValidationFault>;

这是因为你的异常(你知道它真的是FaultException<ValidationFault>)实现了IFaultException<ValidationFault>。由于IFaultException<T>T的协变,这意味着任何IFaultException<ValidationFault>也可以用作IFaultException<IValidationFault>

答案 1 :(得分:0)

我认为通常的方法是创建一个新的Exception实例并设置它的属性(从FaultException复制),或者使用Exception中的一个构造函数,它将一个FaultException作为参数,但这会有点奇怪,因为一个基类不应该了解它的子类。