Java 스타일을 사용하는 방법은 C #에서 키워드를 던지나요?


91

Java에서 throws키워드는 메소드가 자체적으로 예외를 처리하지 않고 호출하는 메소드에 던지도록 선언 할 수 있도록합니다.

C #에 유사한 키워드 / 속성이 있습니까?

동등한 효과가없는 경우 어떻게 동일한 (또는 유사한) 효과를 얻을 수 있습니까?

답변:


78

Java에서는 예외를 처리하거나 throws키워드를 사용하여 예외를 throw 할 수있는 것으로 메소드를 표시해야합니다 .

C #에는이 키워드 나 이에 상응하는 키워드가 없습니다. C #에서와 같이 예외를 처리하지 않으면 잡히거나 잡히지 않으면 프로그램이 종료됩니다.

처리하려면 다음을 수행하십시오.

try
{
  // code that throws an exception
}
catch(ArgumentNullException ex)
{
  // code that handles the exception
  throw;
}

1
"버블 업 (bubble up)", 이것은 자바에서 throws 절이있는 모든 메소드와 동일 함을 의미합니까?
Louis Rhys

1
@Louis RH-종류. 처리되지 않으면 예외가 처리 될 때까지 각 호출 함수를 통해 호출 체인으로 올라갑니다.
Oded 2010-08-12

1
@Louis RH는 완전하지 않습니다. 즉, 코드를 컴파일하려면 최소한 Main에서 Exception을 잡아야했습니다. C #은 확인 된 예외를 알지 못하기 때문에이를 포착하는 것은 사용자의 몫입니다. 그렇지 않으면 런타임에 도착하여 코드를 중단합니다.
Johannes Wachter

1
@jwatcher : 메인 메서드에도 throw 절이있을 수 있습니다.
Louis Rhys

4
@AshishKamble-어. 의견의 문제. .NET에서는 예외 처리가 다릅니다 . "더 나은"것이 무엇인지 알고 있다고 가정하지 마십시오.
Oded

107

op는 키워드가 아닌 Java의 throws절에 해당 하는 C # 에 대해 묻습니다 throw. 이것은 확인 된 예외가 발생할 수 있음을 나타 내기 위해 Java의 메소드 서명에서 사용됩니다.

C #에는 Java 검사 예외와 직접적으로 동등한 것이 없습니다. C #에는 동등한 메서드 서명 절이 없습니다.

// Java - need to have throws clause if IOException not handled
public void readFile() throws java.io.IOException {
  ...not explicitly handling java.io.IOException...
}

번역하다

// C# - no equivalent of throws clause exceptions are unchecked
public void ReadFile() 
{
  ...not explicitly handling System.IO.IOException...
}

30

예, 이것은 오래된 스레드이지만 답변을 검색 할 때 오래된 스레드를 자주 찾아서 내가 찾은 유용한 것을 추가 할 것이라고 생각했습니다.

Visual Studio 2012를 사용하는 경우 IDE 수준에 해당하는 "반복"을 허용하는 데 사용할 수있는 기본 제공 도구가 있습니다.

당신이 사용하는 경우 XML 문서의 댓글 , 위에서 언급 한 바와 같이, 당신은 사용할 수 있습니다 <예외> 왜가 발생하면 나에 대한 정보뿐만 아니라 메소드 또는 클래스에 의해 발생한 예외의 유형을 지정하는 태그를.

예:

    /// <summary>This method throws an exception.</summary>
    /// <param name="myPath">A path to a directory that will be zipped.</param>
    /// <exception cref="IOException">This exception is thrown if the archive already exists</exception>
    public void FooThrowsAnException (string myPath)
    {
        // This will throw an IO exception
        ZipFile.CreateFromDirectory(myPath);
    }

4
OP, 이것이 당신의 대답입니다. 나는 추측하고 있지만 JAVA throws는 개발자에게 유익한 것 외에는 런타임에 아무런 의미가 없습니다. 마찬가지로 @mvanella가 여기서 지적한 것은 정확히 똑같은 작업을 수행하는 C #의 방법입니다. 이 "xml 문서"가 더 중요한 목적을 가지고 있다는 것을 이미 알고 있다고 가정합니다. 이 스레드가 오래되었다는 것을 알고 있습니다.
Hari Lubovac

실제로 Java는 throws절에 명시 적으로 지정 되거나 throw명령에 의해 throw 되지 않는 한 예외를 표시하지 않습니다 . 즉, RunTimeException이 발생하고 발생하는 동일한 메서드에서 처리되지 않으면 실행이 중지됩니다.
Pedro Lima 19

18

다음은 bytes.com에서 방금 찾은 비슷한 질문에 대한 답변입니다 .

짧은 대답은 아니오입니다. C #에는 확인 된 예외가 없습니다. 언어 디자이너는이 인터뷰에서이 결정에 대해 논의합니다.

http://www.artima.com/intv/handcuffs.html

가장 가까운 방법은 XML 문서의 태그를 사용하고 NDoc에서 생성 한 문서를 코드 / 어셈블리와 함께 배포하여 다른 사람들이 어떤 예외를 던지는 지 볼 수 있도록하는 것입니다 (MS가 MSDN 문서에서 정확히 수행하는 작업입니다). 처리되지 않은 예외에 대해 알려주기 위해 컴파일러에 의존 할 수는 없지만 Java에서 익숙 할 수 있습니다.


7

여기에서 대부분의 답변을 살펴본 후 몇 가지 생각을 추가하고 싶습니다.

  1. XML 문서 주석에 의존하고 다른 사람들이 의존하기를 기대하는 것은 좋지 않은 선택입니다. 내가 본 대부분의 C # 코드는 XML 문서 주석으로 메서드를 완전하고 일관되게 문서화하지 않습니다. 그리고 C #에서 예외를 확인하지 않으면 API 사용자가 모든 예외를 개별적으로 처리하는 방법을 알기 위해 메서드에서 throw하는 모든 예외를 어떻게 문서화 할 수 있습니까? 구현에서 throw 키워드로 자신이 던지는 것들에 대해서만 알고 있다는 것을 기억하십시오. 메서드 구현 내에서 사용중인 API는 문서화되지 않았고 구현에서 처리하지 않기 때문에 알지 못하는 예외를 throw 할 수 있습니다. 방법. 다시 말해,

  2. Andreas는 C # 디자인 팀이 확인 된 예외에 대해 결정한 이유에 대한 답변에서 Anders Hejlsberg와의 인터뷰를 연결했습니다. 원래 질문에 대한 최종 답변은 해당 인터뷰에 숨겨져 있습니다.

프로그래머는 어디에서나 try finally를 작성하여 코드를 보호하므로 예외가 발생하면 올바르게 되돌릴 수 있지만 실제로는 예외 처리에 관심이 없습니다.

즉, 항상 모든 곳에서 모든 예외를 포착하므로 특정 API에 대해 어떤 종류의 예외가 예상 될 수 있는지 아무도 관심이 없어야합니다. 그리고 특정 예외에 대해 정말로 관심을 갖고 싶다면,이를 처리하는 방법은 Java throws 키워드와 같은 방식으로 메서드 서명을 정의하는 사람이 아니라 API 사용자에게 특정 예외 처리를 강제하는 것이 아닙니다.

-

개인적으로 저는 여기서 찢어졌습니다. 나는 예외를 확인한 것이 새롭고 다른 문제를 추가하지 않고는 문제를 해결하지 못한다는 Anders의 의견에 동의합니다. XML 문서 주석과 마찬가지로 모든 것이 try finally 블록으로 래핑 된 C # 코드는 거의 표시되지 않습니다. 이것이 실제로 당신의 유일한 선택이며 좋은 습관처럼 보이는 것이지만 나에게 느낍니다.


3

실제로 C #에서 예외를 확인하지 않는 것은 좋거나 나쁜 것으로 간주 될 수 있습니다.

확인 된 예외가 다음과 같은 문제를 제공하기 때문에 나는 그것이 좋은 해결책이라고 생각합니다.

  1. 낮은 수준에서 적절하게 처리 할 수 ​​없기 때문에 비즈니스 / 도메인 계층에 기술 예외가 누출됩니다.
  2. 그들은 API 디자인에서 항상 잘 작동하지 않는 메서드 서명에 속합니다.

그 때문에 대부분의 더 큰 응용 프로그램에서 확인 된 예외가 발생할 때 다음 패턴이 자주 표시됩니다.

try {
    // Some Code
} catch(SomeException ex){
    throw new RuntimeException(ex);
}

이는 본질적으로 C # /. NET이 모든 예외를 처리하는 방식을 에뮬레이션하는 것을 의미합니다.


확인 된 예외가 람다와 어떻게 섞일 지 상상할 수 없습니다!
Gabe

@Gabe : 나는 당신이 그것들을 혼합 할 수있는 몇 가지 개념을 생각 해낼 수있을 것이라고 확신합니다. 그러나 제가 말했듯이, 체크 된 예외는 자바에서도 대부분 좋지 않습니다. 특히 더 복잡한 애플리케이션에서는 더욱 그렇습니다. 따라서 C #에없는 것이 좋습니다.
Johannes Wachter

3

당신은 이것에 대해 묻고 있습니다 :

예외 다시 던지기

public void Method()
{
  try
  {
      int x = 0;
      int sum = 100/x;
  }
  catch(DivideByZeroException e)
  {
      throw;
  }
}

또는

static void Main() 
    {
        string s = null;

        if (s == null) 
        {
            throw new ArgumentNullException();
        }

        Console.Write("The string s is null"); // not executed
    }

3
사용하는 일 throw. 이를 사용하면 스택 추적이 손실되지 않습니다.
Giuseppe Accaputo 2010 년

2

.Net CodeContract EnsuresOnThrow<>와 자바 throws디스크립터 사이에는 몇 가지 일시적인 유사점이 있습니다. 둘 다 함수 나 메서드에서 발생할 수있는 예외 유형으로 호출자에게 신호를 보낼 수 있다는 점에서 두 가지 사이에는 큰 차이가 있습니다.

  • EnsuresOnThrow<>던질 수있는 예외를 명시하는 것 이상이 될뿐만 아니라 예외가 발생하도록 보장되는 조건도 명시합니다. 예외 조건이 식별하기 쉽지 않은 경우 호출 된 메서드에서 상당히 부담스러운 코드가 될 수 있습니다. Java throws는 어떤 예외가 발생할 수 있는지에 대한 표시를 제공합니다 (즉, IMO의 초점은 .Net의 초점이throw 반면, Java에서는 초점이 예외의 가능성을 인식하기 위해 호출자로 이동합니다).
  • .Net CC는 CC 매뉴얼 섹션 2.2.2에서 언급하고 있지만 Java에있는 Checked 예외 와 Unchecked 예외를 구분하지 않습니다.

"호출자가 API의 일부로 예상해야하는 예외에만 예외적 인 사후 조건을 사용하십시오."

  • .Net에서 호출자는 예외가있는 작업을 수행할지 여부를 결정할 수 있습니다 (예 : 계약 비활성화). Java에서 호출자 throws 인터페이스에 동일한 예외에 대해를 추가하더라도 무언가를 수행해야합니다 .

여기에 코드 계약 매뉴얼


0

C # 메서드의 목적이 예외 만 던지는 것이라면 (js 반환 유형이 말한 것처럼) 예외를 반환하는 것이 좋습니다. 아래 예를 참조하십시오.

    public EntityNotFoundException GetEntityNotFoundException(Type entityType, object id)
    {
        return new EntityNotFoundException($"The object '{entityType.Name}' with given id '{id}' not found.");
    }

    public TEntity GetEntity<TEntity>(string id)
    {
        var entity = session.Get<TEntity>(id);
        if (entity == null)
            throw GetEntityNotFoundException(typeof(TEntity), id);
        return entity;
    }


-1

궁금한 사람들을 위해 다음 메소드로 전달하기 위해 잡은 것을 정의 할 필요조차 없습니다. 하나의 메인 스레드에서 모든 오류 처리를 원하는 경우 모든 것을 잡아서 다음과 같이 전달할 수 있습니다.

try {
    //your code here
}
catch {
    //this will throw any exceptions caught by this try/catch
    throw;
}

답변을 수정 해주세요. 실수로 -1을 클릭했습니다. 변경하기 전까지는 삭제할 수 없습니다.
proximab
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.