2013-05-07 24 views
5

zasadzie robię jest konwersja z wyjątek klasy GenericFaultException (kod poniżej urywek używa C# jako język.Generic konwersja

Zobacz szczegóły poniżej

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

FaultException:Exception 

Stworzyłem faultExceptionObject pomocą poniżej linii kodu

public class ValidationFault: IValidationFault 
{ 
} 

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

mam warstwę obsługi błędów, które nie mają żadnego pojęcia o klasie ValidationFault, tylko ona wie 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; 
} 

Z jakiegoś powodu wiersza:

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

skutkuje genericFaultException zawsze równa null, ale z QuickWatch widzę Wyjątek jest typu FaultException<ValidationFault>. Jak należy przekonwertować z Exception na FaultException<IValidationFault>?

Proszę dać mi znać, jeśli potrzebujesz więcej informacji.

góry dzięki

+4

Wygląda jak C#, ale nie powinienem zgadywać. Dodaj odpowiedni tag języka. –

+1

Zdecydowanie chodzi o leki generyczne. –

+0

@Tejas: tak, teraz tak właśnie jest. Ale proszę przeczytaj V1;) – quetzalcoatl

Odpowiedz

3

Powodem exception as FaultException<IValidationFault> jest zerowy, ponieważ jest to FaultException<ValidationFault> nieFaultException<IValidationFault>.

Aby ta operacja działała jak chcesz, FaultException<T> musi być napisane tak, aby T było kowariancyjne. Ale nie możesz tego zrobić w języku C# na zajęcia. Musisz użyć interfejsu. Oto przykład, który powinien działać:

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

Z tej klasy i interfejsu, w dół w kodzie obsługi błędów powinieneś być w stanie to zrobić:

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

To dlatego, że wyjątek (co wiesz jest naprawdę FaultException<ValidationFault>) implementuje IFaultException<ValidationFault>. Ponieważ IFaultException<T> jest kowariantem dla T, oznacza to, że każdy IFaultException<ValidationFault> może być również używany jako IFaultException<IValidationFault>.

+0

Dzięki Brandon, tego właśnie oczekiwałem. –

+0

Cool. Nie zapomnij przyjąć odpowiedzi, jeśli rzeczywiście to pytanie. – Brandon

0

myślę normalny sposób jest, aby utworzyć nową instancję wyjątku i ustawić jego właściwości (kopiowanie z FaultException), lub za pomocą konstruktora wewnątrz wyjątek, który pobiera FaultException jako argument, ale to być trochę dziwnym, ponieważ klasa bazowa nie powinna mieć wiedzy na temat jej podklasy.