2013-05-07 5 views
5

В основном я делаю преобразование из исключений в класс GenericFaultException (Ниже фрагмент кода использует C# как язык.Generic преобразования

Смотрите детали ниже

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 всегда равна нулю, но из QuickWatch я вижу Исключение типа FaultException<ValidationFault>. Как мне перевести с Exception в FaultException<IValidationFault>?

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

Заранее спасибо

+4

Похож на C#, но я не должен был догадываться. Добавьте соответствующий тег языка. –

+1

Это определенно о дженериках. –

+0

@Tejas: да, теперь это на самом деле. Но, пожалуйста, прочитайте V1;) – quetzalcoatl

ответ

3

Причина exception as FaultException<IValidationFault> равна нулю, так как это FaultException<ValidationFault> является не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>.

+0

Спасибо Брэндон, этого я и ожидал. –

+0

Прохладный. Не забудьте принять ответ, если это действительно ответит на вопрос. – Brandon

0

Я думаю, что нормальный способ, чтобы создать новый экземпляр Exception и установить его свойства (копирование с FaultException), или с помощью конструктора в пределах Exception, который принимает FaultException в качестве аргумента, но это будет быть немного странным, потому что базовый класс не должен иметь знаний о своих подклассах.

Смежные вопросы