예외 만들기 및 Throw(C# 프로그래밍 가이드)Creating and Throwing Exceptions (C# Programming Guide)

예외는 프로그램을 실행하는 동안 오류가 발생했음을 나타내는 데 사용됩니다.Exceptions are used to indicate that an error has occurred while running the program. 오류를 설명하는 예외 개체가 만들어지고 throw 키워드를 통해 throw됩니다.Exception objects that describe an error are created and then thrown with the throw keyword. 그런 다음 런타임에 가장 호환성이 높은 예외 처리기를 검색합니다.The runtime then searches for the most compatible exception handler.

프로그래머는 다음 조건 중 하나 이상에 해당할 경우 예외를 throw해야 합니다.Programmers should throw exceptions when one or more of the following conditions are true:

  • 메서드가 정의된 기능을 완료할 수 없는 경우.The method cannot complete its defined functionality.

    예를 들어 메서드에 대한 매개 변수에 잘못된 값이 포함된 경우입니다.For example, if a parameter to a method has an invalid value:

    static void CopyObject(SampleClass original)
    {
        if (original == null)
        {
            throw new System.ArgumentException("Parameter cannot be null", "original");
        }
    
    }
    
  • 개체 상태에 따라 개체에 대한 부적절한 호출이 이루어진 경우.An inappropriate call to an object is made, based on the object state.

    한 가지 예는 읽기 전용 파일에 쓰려고 시도하는 경우입니다.One example might be trying to write to a read-only file. 개체 상태가 작업을 허용하지 않을 경우 이 클래스의 파생에 따라 InvalidOperationException의 인스턴스 또는 개체를 throw합니다.In cases where an object state does not allow an operation, throw an instance of InvalidOperationException or an object based on a derivation of this class. 다음은 InvalidOperationException 개체를 throw하는 메서드의 예제입니다.This is an example of a method that throws an InvalidOperationException object:

    class ProgramLog
    {
        System.IO.FileStream logFile = null;
        void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}
    
        void WriteLog()
        {
            if (!this.logFile.CanWrite)
            {
                throw new System.InvalidOperationException("Logfile cannot be read-only");
            }
            // Else write data to the log and return.
        }
    }
    
  • 메서드에 대한 인수가 예외를 일으키는 경우.When an argument to a method causes an exception.

    이 경우 원래 예외가 catch되고 ArgumentException 인스턴스가 만들어져야 합니다.In this case, the original exception should be caught and an ArgumentException instance should be created. 원래 예외를 ArgumentException의 생성자에 InnerException 매개 변수로 전달해야 합니다.The original exception should be passed to the constructor of the ArgumentException as the InnerException parameter:

    static int GetValueFromArray(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException ex)
        {
            System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);
            throw argEx;
        }
    }
    

예외에 이름이 StackTrace인 속성이 포함되어 있습니다.Exceptions contain a property named StackTrace. 이 문자열에는 현재 콜 스택에 대한 메서드의 이름과 각 메서드에 대해 예외가 throw된 파일 이름 및 줄 번호가 포함됩니다.This string contains the name of the methods on the current call stack, together with the file name and line number where the exception was thrown for each method. StackTrace 개체는 throw 문의 지점에서 CLR(공용 언어 런타임)에 의해 자동으로 만들어지므로 해당 예외는 스택 추적이 시작되는 지점에서 throw되어야 합니다.A StackTrace object is created automatically by the common language runtime (CLR) from the point of the throw statement, so that exceptions must be thrown from the point where the stack trace should begin.

모든 예외에 이름이 Message인 속성이 포함되어 있습니다.All exceptions contain a property named Message. 예외의 이유를 설명하려면 이 문자열을 설정해야 합니다.This string should be set to explain the reason for the exception. 보안이 중요한 정보는 메시지 텍스트에 넣으면 안 됩니다.Note that information that is sensitive to security should not be put in the message text. Message 외에 ArgumentException에는 예외를 throw한 인수의 이름으로 설정해야 하는 ParamName 속성이 포함되어 있습니다.In addition to Message, ArgumentException contains a property named ParamName that should be set to the name of the argument that caused the exception to be thrown. 속성 setter의 경우 ParamNamevalue로 설정해야 합니다.In the case of a property setter, ParamName should be set to value.

public 및 protected 메서드는 의도한 함수를 완료할 수 없을 때마다 예외를 throw해야 합니다.Public and protected methods should throw exceptions whenever they cannot complete their intended functions. throw된 예외 클래스는 오류 조건에 맞을 수 있는 가장 구체적인 예외여야 합니다.The exception class that is thrown should be the most specific exception available that fits the error conditions. 이러한 예외는 클래스 기능의 일부로 문서화해야 하고 파생 클래스 또는 원래 클래스의 업데이트는 이전 버전과의 호환성을 위해 같은 동작을 유지해야 합니다.These exceptions should be documented as part of the class functionality, and derived classes or updates to the original class should retain the same behavior for backward compatibility.

예외를 throw할 때 피해야 하는 작업Things to Avoid When Throwing Exceptions

다음 목록은 예외를 throw할 때 피해야 할 사례를 나타냅니다.The following list identifies practices to avoid when throwing exceptions:

  • 프로그램 흐름을 일반 예외의 일부로 변경하는 데는 예외를 사용하면 안 됩니다.Exceptions should not be used to change the flow of a program as part of ordinary execution. 오류 조건을 보고하고 처리하는 데만 예외를 사용해야 합니다.Exceptions should only be used to report and handle error conditions.

  • 예외는 throw하는 대신 반환 값 또는 매개 변수로 반환하면 안 됩니다.Exceptions should not be returned as a return value or parameter instead of being thrown.

  • 고유한 소스 코드에서 의도적으로 System.Exception, System.SystemException, System.NullReferenceException 또는 System.IndexOutOfRangeException을 throw하지 마세요.Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.

  • 릴리스 모드가 아닌 디버그 모드에서 throw될 수 있는 예외를 만들지 마세요.Do not create exceptions that can be thrown in debug mode but not release mode. 개발 단계에서 런타임 오류를 식별하려면 대신 디버그 어설션을 사용하세요.To identify run-time errors during the development phase, use Debug Assert instead.

예외 클래스 정의Defining Exception Classes

프로그램에서는 System 네임스페이스의 미리 정의된 예외 클래스를 throw하거나(이전에 언급한 위치 제외) Exception에서 파생시켜 자체 예외 클래스를 만들 수 있습니다.Programs can throw a predefined exception class in the System namespace (except where previously noted), or create their own exception classes by deriving from Exception. 파생 클래스는 매개 변수 없는 생성자, 메시지 속성을 설정하는 생성자, MessageInnerException 속성을 설정하는 생성자 두 개를 포함하여 네 개 이상의 생성자를 정의해야 합니다.The derived classes should define at least four constructors: one parameterless constructor, one that sets the message property, and one that sets both the Message and InnerException properties. 네 번째 생성자는 예외를 serialize하는 데 사용됩니다.The fourth constructor is used to serialize the exception. 새 예외 클래스는 serialize할 수 있어야 합니다.New exception classes should be serializable. 예:For example:

[Serializable()]
public class InvalidDepartmentException : System.Exception
{
    public InvalidDepartmentException() : base() { }
    public InvalidDepartmentException(string message) : base(message) { }
    public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }

    // A constructor is needed for serialization when an
    // exception propagates from a remoting server to the client. 
    protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}

새로운 속성이 제공하는 데이터가 예외 확인에 유용할 경우에만 해당 속성을 예외 클래스에 추가해야 합니다.New properties should only be added to the exception class when the data they provide is useful to resolving the exception. 새 속성이 파생 예외 클래스에 추가되면 추가된 정보를 반환하기 위해 ToString()을 재정의해야 합니다.If new properties are added to the derived exception class, ToString() should be overridden to return the added information.

C# 언어 사양C# Language Specification

자세한 내용은 C# 언어 사양예외throw 문을 참조하세요.For more information, see Exceptions and The throw statement in the C# Language Specification. 언어 사양은 C# 구문 및 사용법에 대 한 신뢰할 수 있는 소스 됩니다.The language specification is the definitive source for C# syntax and usage.

참고 항목See also