2010-12-03 4 views
0

Этот вопрос задан по-разному раньше, но ответы мне не помогают, потому что (1) у меня нет контроля над встроенными классами Exception и (2) Activator.CreateInstance() возвращает объект/экземпляр, где мне нужен настоящий динамический тип.Метод расширения для исключения, требующий динамического типа generic

Я пытаюсь создать метод расширения, который позволяет мне выкинуть FaultException из моей службы WCF, основываясь на исключении, которое я поймаю. Например:

try { 
    ... 
} 
catch (ArgumentNullException exc) { 
    throw new FaultException<ArgumentNullException>(exc); 
} 

- прямолинейный. Но если я хочу, чтобы расширить это в общем виде, я бы использовать класс расширения, например:

try { 
    ... 
} 
catch (Exception exc) { 
    exc.ThrowFaultException(); 
} 

Где я зацикливаться, конечно, является реализация метода расширения:

public static void ThrowFaultException(this Exception exc) { 

    // Gives me the correct type... 
    Type exceptionType = exc.GetType(); 

    // But how the heck do I use it? 
    throw new FaultException<???>(exc); 
} 

Ответы here и here не помогают. Есть идеи?

+0

Почему» t вы отбрасываете возврат из `Activator.CreateInstance()` в `Exception`? Он по-прежнему будет выброшен как его фактический тип, нет? – 2010-12-03 19:02:01

+0

Это хорошая идея, чтобы генерировать исключение из пользовательского кода, а не из некоторого обобщенного метода. Это поможет VS.Net и другим анализаторам кода (включая ваши сверстники) для обнаружения недостижимого кода и связанных с ним проблем. – 2010-12-03 19:31:03

+0

BR/DP> То, что я обнаружил, когда тестировал это решение, заключалось в том, что вызывающий вызывал исключение из общего обработчика catch (Exception exc) {}, а не обработчика для FaultException 2010-12-03 19:39:31

ответ

3

Попробуйте это:

public static void ThrowFaultException<TException>(this TException ex) where TException : System.Exception 
{ 
    throw new FaultException<TException>(ex); 
} 
1

Вам не нужно бросать объект, возвращенный Activator.CreateInstance to FaultException <? >, чтобы бросить его. Кастинг его Exception достаточно:

var type = typeof(FaultException<>).MakeGenericType(exc.GetType()); 

throw (Exception)Activator.CreateInstance(type, exc); 

Я бы не бросить исключение в ThrowFaultException хотя:

try 
{ 
    ... 
} 
catch (Exception e) 
{ 
    throw e.WrapInFaultException(); 
} 

public static Exception WrapInFaultException(this Exception e) 
{ 
    var type = typeof(FaultException<>).MakeGenericType(e.GetType()); 

    return (Exception)Activator.CreateInstance(type, e); 
} 
1
public static void ThrowFaultException(this Exception exc) 
    { 
     // Gives me the correct type... 
     Type exceptionType = exc.GetType(); 
     var genericType = typeof(FaultException<>).MakeGenericType(exceptionType); 
     // But how the heck do I use it? 
     throw (Exception)Activator.CreateInstance(genericType, exc); 
    } 
Смежные вопросы