2009-10-16 2 views
39

입력에 따라 예외를 던질 수있는 코드에 대한 단위 테스트를 수행하고있었습니다. 그래서 아래의 코드 같은 시도 : (예 단순화)C#에서 제네릭 예외를 잡을 수없는 이유는 무엇입니까?

static void Main(string[] args) 
    { 
     RunTest<ArgumentException>(); 
    } 

    static void RunTest<T>() where T : Exception, new() 
    { 
     try 
     { 
      throw new T(); 
      //throw new ArgumentException(); <-- Doesn't work either 

     } 
     catch (T tex) 
     { 
      Console.WriteLine("Caught passed in exception type"); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Caught general exception"); 
     } 
     Console.Read(); 
    } 

을하지만 항상 핸들러가 작동하지 않을 것 "겁에 질린 일반 예외"를 캐치 (T 텍스)를 출력합니다. 내가 T()를 던지 던지 명시 적으로 ArgumentException()을 던지 든 상관 없습니다. 이게 왜 어떤 아이디어일까요? 사실 나는 catch 절에서 T를 사용할 수 있다는 것에 놀랐지 만 가능한 것은 가능하지 않기 때문에? 아니면 최소한이 컴파일러가 작동하지 않을 것이라고 말하는 컴파일러 경고/오류를 제공합니까?

내 환경은 Visual Studio 2008 및 3.5 대상 프레임 워크입니다.

업데이트 : 이제 명령 프롬프트에서 직접 시도한 다음 "예외 유형으로 잡혔습니다"라는 메시지를 인쇄합니다. 따라서 Visual Studio 내에서 실행되는 것으로 제한되어 있습니다. 어쩌면 Visual Studio 호스팅 프로세스의 특이점일까요?

+1

보다 디버거에서 실행과 더 그리고는 예외 유형에 전달 잡았어 인쇄. 환경 및 프레임 워크 버전에 대한 자세한 정보를 제공 할 수 있습니까? –

+2

그건 재미 있어요. VS2008의 콘솔 앱으로 실행했는데 일반 예외가 잡혔습니다. –

+0

SnippetCompiler –

답변

32

여기 기괴한 행동 ...

VS2k8 콘솔 앱. 다음 : "겁에 질린 일반 예외"에서

try 
{ 
    throw new T(); 
} 
catch (T tex) 
{ 
    Console.WriteLine("Caught passed in exception type"); 
} 
catch (Exception ex) 
{ 
    Console.WriteLine("Caught general exception"); 
} 

결과.

그러나, catch 문에서 (쓸모없는) 변수를 제거 :에

try 
{ 
    throw new T(); 
} 
catch (T) 
{ 
    Console.WriteLine("Caught passed in exception type"); 
} 
catch (Exception) 
{ 
    Console.WriteLine("Caught general exception"); 
} 

결과 "예외 유형에 전달 잡았다"!


업데이트 :

헤헤 ... 그 버그 : https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=362422&wa=wsignin1.0

소스? 이리. Why does catch(TException) handling block behaviour differ under the debugger after installing Visual Studio 2008?

2

예외의 가장 구체적인 유형이 주어 졌을 때 것으로 보인다 T와 Exception 사이의 선택은 예외이며, 그래서 핸들러가 호출된다.

방금 ​​시도했는데 (C#이나 VB에서는 할 수 없지만 IL을 편집했습니다.) 두 번째 catch 절이 Exception Ex보다 Object Ex를 catch하도록 변경되었으며이 경우 첫 번째 처리기 맞았다.

편집

다른 사람들이 지적했듯이, 그것은 그냥 LinqPad에서 시험되는 특정 유형의

관련 문제