C# 전처리기 지시자 마스터하기: 실전 가이드
C# 전처리기 지시자 완벽 가이드
C# 전처리기 지시자가 컴파일 제어, 조건부 컴파일, 오류 처리에 어떻게 활용되는지 각 지시자의 문법, 실전 예제, 모범 사례와 함께 상세히 다룹니다.
전처리기 지시자는 실제 컴파일이 시작되기 전에 컴파일러가 평가하는 명령입니다. 어떤 코드 섹션을 포함할지, 경고와 오류를 어떻게 처리할지, 심지어 컴파일러의 줄 번호와 파일명 인식까지 변경할 수 있습니다.
C#에서 지시자는 # 기호로 시작하며, 세미콜론이 아닌 줄바꿈으로 끝나는 단일 라인입니다.
C# 주요 전처리기 지시자
| 지시자 | 설명 | 문법 |
#if | 전처리 표현식을 평가하여 참일 때만 코드 포함 | #if expression
code
#endif |
#elif | #if 뒤에 추가 조건 테스트 | #if expr1
code1
#elif expr2
code2
#endif |
#else | 앞선 #if/#elif 조건이 모두 거짓일 때 실행 | #if expr1
code1
#else
code2
#endif |
#endif | 조건부 블록 종료 | #if expr
code
#endif |
#define | 새 심볼 정의 | #define SYMBOL |
#undef | 정의된 심볼 제거 | #undef SYMBOL |
#warning | 사용자 정의 컴파일 경고(레벨 1) 발생 | #warning Your warning message |
#error | 컴파일 타임 오류 발생 | #error Your error message |
#line | 컴파일러의 줄 번호/파일명 재정의(진단용) | #line 50 "FakeProgram.cs" |
#region | 에디터(Visual Studio 등)에서 접을 수 있는 영역 생성 | #region Description
code
#endregion |
#pragma | 컴파일러 특수 명령 전달(경고 활성화/비활성화 등) | #pragma warning disable |
심볼 정의 및 해제
- #define:
#if 블록에서 참으로 평가되는 심볼 생성
- #undef: 심볼 제거하여 거짓으로 평가되게 함
예제: 심볼 정의
#define TESTING
예제: 심볼 해제
#undef TESTING
조건부 컴파일: #if, #elif, #else, #endif
#if: 표현식 테스트, 참일 때만 내부 코드 컴파일
- 논리 연산자(
&&, ||, !)와 심볼 사용 가능
#elif: 여러 조건 순차 테스트
#else: 앞선 조건 모두 불만족 시 실행
#endif: 조건부 블록 종료
실전 예제
#define CSHARP
#undef PYTHON
using System;
namespace Directive {
class ConditionalDirective {
static void Main(string[] args) {
#if (CSHARP && PYTHON)
Console.WriteLine("CSHARP and PYTHON are defined");
#elif (CSHARP && !PYTHON)
Console.WriteLine("CSHARP is defined, PYTHON is undefined");
#elif (!CSHARP && PYTHON)
Console.WriteLine("PYTHON is defined, CSHARP is undefined");
#else
Console.WriteLine("CSHARP and PYTHON are undefined");
#endif
}
}
}
출력: CSHARP is defined, PYTHON is undefined
경고 및 오류 생성
#warning: 사용자 정의 경고 발생, 컴파일은 계속 진행
#error: 치명적 오류 발생, 컴파일 중단
경고 예제
using System;
namespace Directives {
class WarningDirective {
public static void Main(string[] args) {
#if (!CSHARP)
#warning CSHARP is undefined
#endif
Console.WriteLine("#warning directive example");
}
}
}
경고 라인이 출력되지만 콘솔 텍스트도 정상 출력됩니다.
오류 예제
using System;
namespace Directive {
class Error {
public static void Main(string[] args) {
#if (!CSHARP)
#error CSHARP is undefined
#endif
Console.WriteLine("#error directive example");
}
}
}
출력: 컴파일 타임 오류로 빌드 실패, 마지막 콘솔 라인은 실행되지 않음.
#line으로 진단 위치 커스터마이징
- 이후 경고/오류에 표시될 줄 번호와 파일명 변경
예제
using System;
namespace Directive {
class LineDemo {
public static void Main(string[] args) {
#line 200 "AnotherProgram.cs"
#warning Actual warning generated by Program.cs on line 10
}
}
}
결과: 경고가 AnotherProgram.cs(200,22): warning CS1030: ... 형태로 표시됨.
#region과 #endregion으로 코드 구성
- 관련 코드 블록 그룹화, 에디터에서 접기/펼치기 가능
- 다른
#region과 겹칠 수 없으나 조건부 블록 내부에 위치 가능
예제
using System;
namespace Directive {
class RegionDemo {
public static void Main(string[] args) {
#region Hello
Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");
#endregion
}
}
}
출력: "Hello" 5줄.
#pragma로 고급 컴파일러 제어
- 컴파일러 동작 세밀 제어
- 주요 용도:
#pragma warning disable: 모든 경고 끄기
#pragma warning restore: 경고 다시 켜기
- 특정 경고 번호 지정 가능(예:
#pragma warning disable CS0168)
#pragma checksum: 디버깅용 체크섬 생성
예제
using System;
namespace Directive {
class PragmaDemo {
public static void Main(string[] args) {
#pragma warning disable
#warning This is a warning 1
#pragma warning restore
#warning This is a warning 2
}
}
}
두 번째 경고만 표시됩니다.
더 자세한 내용은 공식 #pragma (C# 참조)를 참조하세요.