Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic conversion

Basically I'm doing is converting from Exception to GenericFaultException class (The below code snippet uses C# as a language.

See the below details

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

FaultException:Exception

I have created a faultExceptionObject using the below line of code

public class ValidationFault: IValidationFault
{
}

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

I have a Error handling layer which do not have any idea about ValidationFault class,only it knows 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;
 }

For some reason the line:

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

results in genericFaultException always equal to null, but from the QuickWatch I see Exception is of type FaultException<ValidationFault>. How should I convert from Exception to FaultException<IValidationFault>?

Please let me know if you need any more information.

Thanks in advance

like image 401
IT Fresher Avatar asked Oct 22 '22 10:10

IT Fresher


1 Answers

The reason exception as FaultException<IValidationFault> is null is because a FaultException<ValidationFault> is not a FaultException<IValidationFault>.

For this operation to work as you want, FaultException<T> must be written so that T is covariant. But you cannot do that in c# for classes. You have to use an interface. Here is an example that should work:

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;
    }
}

With this class and interface, down in your error handling code you should be able to do:

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

This is because your exception (which you know is really a FaultException<ValidationFault>) implements IFaultException<ValidationFault>. Since IFaultException<T> is covariant for T, this means any IFaultException<ValidationFault> can also be used as IFaultException<IValidationFault>.

like image 72
Brandon Avatar answered Oct 27 '22 12:10

Brandon