Programing

C #에서 '널 던지기'를 허용하는 이유는 무엇입니까?

lottogame 2020. 10. 17. 08:57
반응형

C #에서 '널 던지기'를 허용하는 이유는 무엇입니까?


특히 복잡한 예외 처리 코드를 작성하는 동안 누군가가 물었습니다. 예외 객체가 null이 아닌지 확인할 필요가 없습니까? 그리고 나는 물론 아니라고 말했지만 시도하기로 결정했습니다. 분명히 null을 던질 수 있지만 여전히 어딘가에서 예외로 바뀝니다.

왜 이것이 허용됩니까?

throw null;

이 스 니펫에서 고맙게도 'ex'는 null이 아니지만 그럴 수 있습니까?

try
{
  throw null;
}
catch (Exception ex)
{
  //can ex ever be null?

  //thankfully, it isn't null, but is
  //ex is System.NullReferenceException
}

언어 사양은 유형의 표현식을 예상하고 System.Exception(따라서 null해당 컨텍스트에서 유효 함)이 표현식을 널이 아닌 것으로 제한하지 않기 때문입니다. 일반적으로 해당 표현식의 값이 맞는지 여부를 감지 할 수있는 방법은 null없습니다. 중지 문제를 해결해야합니다. null어쨌든 런타임은 케이스 를 처리해야 합니다. 보다:

Exception ex = null;
if (conditionThatDependsOnSomeInput) 
    ex = new Exception();
throw ex; 

물론 그들은 null리터럴을 무효화 하는 특정한 경우를 만들 수는 있지만 그다지 도움이되지 않을 것입니다. 그렇다면 왜 사양 공간을 낭비하고 적은 이익을 위해 일관성을 줄여야할까요?

면책 조항 (Eric Lippert에게 맞기 전) : 이것은 이 디자인 결정의이면에있는 이유에 대한 저의 추측입니다. 물론 저는 디자인 회의에 참석하지 않았습니다.)


두 번째 질문에 대한 답은 catch 절 내에서 잡힌 식 변수가 null 일 수 있는지 여부입니다. C # 사양은 다른 언어로 인해 null예외가 전파 될 수 있는지 여부에 대해 침묵하지만 예외가 전파되는 방식을 정의합니다.

catch 절 (있는 경우)은 예외에 대한 적절한 핸들러를 찾기 위해 나타나는 순서대로 검사됩니다. 예외 유형 또는 예외 유형의 기본 유형을 지정하는 첫 번째 catch 절 은 일치로 간주됩니다. 일반적인 catch 절은 모든 예외 유형에 대한 일치로 간주됩니다. [...]

의 경우 null굵은 글씨는 거짓입니다. 따라서 순전히 C # 사양에 따르면 기본 런타임이 null을 throw하지 않는다고 말할 수는 없지만이 경우에도 일반 catch {}절에 의해서만 처리된다는 것을 확신 할 수 있습니다 .

CLI에서 C # 구현의 경우 ECMA 335 사양을 참조 할 수 있습니다. 이 문서는 CLI가 내부적으로 던지는 모든 예외를 정의하고 (아무것도 아님 null) 사용자 정의 예외 객체가 throw명령어에 의해 throw된다는 것을 언급합니다 . 해당 명령어에 대한 설명은 C # throw문과 거의 동일 합니다 (객체 유형을로 제한하지 않는다는 점 제외 System.Exception).

기술:

throw명령어는 O스택 에서 예외 객체 (type )를 throw하고 스택을 비 웁니다. 예외 메커니즘에 대한 자세한 내용은 파티션 I을 참조하십시오.
[참고 : CLI는 모든 개체의 throw를 허용하지만 CLS는 언어 상호 운용성을 위해 사용해야하는 특정 예외 클래스를 설명합니다. 끝 참고]

예외 :

System.NullReferenceException경우에 발생합니다 obj입니다 null.

단정:

올바른 CIL은 객체가 항상 null또는 객체 참조 (즉, 유형 O)인지 확인합니다.

나는 이것들이 잡힌 예외가 결코 없다고 결론 짓기에 충분하다고 믿는다 null.


분명히 null을 던질 수 있지만 여전히 어딘가에서 예외로 바뀝니다.

null객체 를 던지려고 하면 (완전히 관련이없는) Null 참조 예외가 발생합니다.

던질 수있는 null이유를 묻는 것은 왜 이렇게 할 수 있는지 묻는 것과 같습니다.

object o = null;
o.ToString();

While it may not be possible to throw null in C# because the throw will detect that and turn it into a NullReferenceException, it IS possible to receive null... I happen to be receiving that right now, which causes my catch (which was not expecting 'ex' to be null) to experience a null reference exception which then results in my app dying (since that was the last catch).

So, while we can't throw null from C#, the netherworld can throw null, so your outermost catch(Exception ex) better be prepared to receive it. Just FYI.


Taken from here:

If you use this expression in your C# code it will throw a NullReferenceException. That is because the throw-statement needs an object of type Exception as its single parameter. But this very object is null in my example.


I think maybe you can't -- when you try to throw null, it can't, so it does what it should in an error case, which is throw a null reference exception. So you're not actually throwning the null, you're failing to throw the null, which results in a throw.


Trying to answer "..thankfully 'ex' is not null, but could it ever be?":

Since we arguably cannot throw exceptions that is null, a catch clause will also never have to catch an exception that is null. Thus, ex could never be null.

I see now that this question has in fact already been asked.


Remember that an exception includes details as to where the exception is thrown. Seeing as the constructor has no idea where it is to be thrown, then it only makes sense that the throw method injects those details into the object at the point the throw is. In other words the CLR is attempting to inject data into null, which triggers a NullReferenceException.

Not sure if this is exactly what is happening, but it explains the phenomenon.

Assuming this is true (and I can't think a better way to get ex to be null than throw null;), that would mean that ex cannot possibly be null.

참고URL : https://stackoverflow.com/questions/2195764/why-does-c-sharp-allow-you-to-throw-null

반응형