NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# 23-1. C#의 특성 (Attributes)

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 오랫만에 C#에 대한 글을 적게 되네요-_-; 모바일 관련 사업 준비로, 요즘 Xamarin에 대해 공부(?)하는 중입니다. Objective C와 Android SDK를 공부하는 것 보다는 크로스 플랫폼 개발 Tool과 언어를 익히는게 더 유리하다는 판단입니다. 물론, 이렇게 판단하게 된 가장 큰 요인은 Xamarin의 언어가 C#이라는 점입니다.

     

    아무래도 익숙한 언어와 익숙한 IDE를 사용한다는건 개발자에게 큰 메리트죠. 대부분 새로운 언어와 새로운 툴, 환경에서 오는 시행착오와 최적화되지 않은 코드의 양산으로 스트레스를 많이 받을겁니다. 레퍼런스가 별로 없는 새로운 언어라면 문제는 더 커집니다-_-;

     

    C#의 특성은 선언 정보를 형식(구조체, 클래스, 열거형, 대리자)과 맴버(메서드, 필드, 이벤트, 속성, 인덱서)에 연결하는 강력한 방법을 제공합니다. 프로그램 엔터티와 연결되면 특성은 런타임에서 쿼리되어 여러 방식으로 사용될 수 있습니다. 아마도, 대부분의 개발자들이 win32의 도움을 필요로 하거나 그외 C#으로 구현하기 힘든 부분들을 관리되지 않는 코드(Unmanaged Code)로 작성할 때 주로 DllImport 특성을 이용하여 개발을 진행 했을겁니다. 그외에도 클래스의 메타데이타를 설정하거나 전처리기와 협력하기도 하고, 데이터모델에 대해 제약을 걸수도 있습니다.

     

    특성에 대한 아래 예제를 통해 어느정도 학습하는데 도움이 되었으면 좋겠네요-_-;

     

    특성 클래스는 최소한 하나의 공용 생성자가 있는 System.Attribute에서 파생된 공용 클래스로 2가지 형식의 매개 변수가 있습니다.

    • 위치 매개 변수는 특성을 사용할 때마다 지정해야 합니다. 위치 매개 변수는 특성 클래스의 생성자 인수로 지정됩니다.

    • 명명된 매개 변수는 선택 사항으로, 특성을 사용할 때 이를 지정하면 매개 변수 이름을 반드시 사용해야 합니다. 비정적 필드나 속성이 있으면 명명된 매개 변수가 정의됩니다.

     

     

    특성의 기본 형식입니다.

    [attribute명(Positional_Parameter, Optional_Parameter = Value, ...)]

     

     

    특성 매개 변수는 다음 형식의 상수 값만 사용할 수 있습니다.

    • 단순 형식(bool, byte, char, short, int, long, float, double)

    • string

    • System.Type

    • enums

    • 개체(형식 개체의 특성 매개 변수에 대한 인수는 위 형식의 상수 값이어야 함)

    • 위 형식의 모든 1차원 배열

     

     

    아래 예제는 전처리기와 특성을 이용하여 선택적으로 로그를 기록하는 방법을 나타내고 있습니다.

    ConditionalMethod.cs

    #if(DEBUG)
    #define LOGGING
    #endif
    
    using System;using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    
    namespace Attributes
    {
        class ConditionalMethod
        {
            [Conditional("LOGGING")]
            public void LogWriter()
            {
                Console.WriteLine("로그를 기록했습니다.");
            }
    
            public static void Main()
            {
                var pgm = new ConditionalMethod(); 
                pgm.LogWriter(); 
                Console.ReadKey();
            }
        }
    }

     

     

    위 코드의 1~3라인은 전처리기의 조건문입니다. 이렇게 DEBUG 상수를 통해 조건을 만들고, 빌드 옵션에 따라서 처리를 분기할수도 있습니다. 보통 운영에 배포할 때 릴리즈 모드로 배포하기 때문에 개발 단계에서 임의로 처리하거나 가상 데이터 바인딩, 개발 단계에만 사용하는 Trace Logging등에 사용됩니다. 하지만, 대부분은 AOP(Aspect Oriented Programming)를 도입하고 있어서 일부러 위와 같은 예제처럼 전처리기를 이용하거나 하지는 않습니다. 사실 많은 제품들이 이미 나와 있기 때문에 구입해서 사용하는 편입니다. 직접 만들어서 사용하는 곳은 아직까지 보질 못했네요^^;

     

    15라인에서 System.Diagnostics 네임스페이스에 있는 Conditional 특성을 사용하고 있습니다. 2라인에 #define 전처리기로 LOGGING이 정의되어 있기 때문에 Conditional의 값인 LOGGING이 처리됩니다. 이 특성은 정의되어 있는 기호가 있으면 메소드를 컴파일하고 정의가 없으면 메소드는 컴파일에서 제외됩니다. 또한, 제외된 메소드는 다른곳에서 호출하는 모든 코드도 제외시킵니다.

     

    비주얼 스튜디오에서 빌드 옵션을 Debug로 선택한 후 실행(F5)하세요.

    9nXsjVy.png

     

     

    정상적으로 실행됩니다.

    laFwOvJ.png

     

     

    Debug를 Release로 변경한 후 실행하면 아래 그림처럼 아무것도 출력되지 않습니다. 물론, 메소드가 컴파일러에 의해 제외되었지만 Main에서 호출하더라도 에러가 발생되지 않습니다. 호출도 모두 제외 되었기 때문이죠.

    AZIiNka.png

     

     

    다음은 은근히 많이 사용되는 Obsolete 특성에 대해 알아보겠습니다. 이 특성은 이곳에서도 여러번 다룬적이 있습니다. 직접적으로 알아보거나 하지는 않았지만, 어떻게 사용되는지 언급만 하고 넘어간거 같네요^^;

    아래와 같이 코드를 변경하세요.

    ConditionalMethod.cs

    #if(DEBUG)
    #define LOGGING
    #endif
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    
    namespace Attributes
    {    
        [Obsolete("AOP 클래스를 사용하세요.")]    
        class ConditionalMethod

     

     

    위 코드의 13라인처럼 Obsolete특성을 추가하고 이 클래스는 더이상 사용되지 않음을 개발자에게 알릴 수 있습니다. 아래 그림을 보면 이 클래스를 사용하려는 개발자는 경고 메시지와 함께 대안을 제안 받고 있습니다.

    ioJ1ExG.png

     

     

    하지만, 이런 제안에도 불구하고 Syntax의 변경과 복잡한 사용성으로 인해 익숙한 클래스를 사용하려는 개발자도 있을 수 있습니다. 어떤 상호작용으로 인해 오류가 발생되거나 또는 오류는 없지만 약간의 성능 하향이라면 말이죠. 이런 것들은 쉽게 발견되지도 않고 특별한 문제를 발생시키지 않을겁니다. 당장은요. 그래서, 강제로 제안된 클래스나 메소드를 사용하게 유도할 수 있습니다. Obsolete의 두번째 인자로 true를 넘기기만 하면 됩니다.

     

    두번째 인자로 true를 넘기는 것은 상당히 조심스러워야 합니다. 예로, Core 또는 Base코드거나 Framework라면 말이죠. 이 프레임워크를 사용하는 수많은 시스템에서 동시에 코드를 변경하는건 사실상 불가능에 가깝습니다. 각각의 시스템마다 배포일정이나 운영팀의 개발 일정이 정해져 있기 때문이죠. 그래서 아주 심각한(?) 버그가 아닌 경우에는 사용되지 않습니다.

    아래처럼 코드를 변경하고 실행(F5) 해보세요.

    ConditionalMethod.cs

        [Obsolete("AOP 클래스를 사용하세요.", true)]

     

     

    아래 그림처럼 컴파일되지 않으며 오류 메시지를 표시합니다.

    BwZUbrL.png

     

     

    다음에는 외부 라이브러리를 사용할 수 있는 DllImport특성과 사용자가 직접 특성을 만들고 사용하는 방법에 대해 알아보겠습니다.

    다음 시간에...

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.