2022년 1월 31일 월요일

[동영상]C# 어트리뷰트(Attribute) Conditional, Obsolete, DllImport 사용자정의 Attribute작성, C#교육, C#학원, C#동영상, 닷넷학원, 닷넷교육

 [동영상]C# 어트리뷰트(Attribute)  Conditional, Obsolete, DllImport  사용자정의 Attribute작성, C#교육, C#학원, C#동영상, 닷넷학원, 닷넷교육


http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=405 


[동영상]C# 어트리뷰트(Attribute) Conditional, Obsolete, DllImport 사용자정의 Attribute작성

[동영상]C# 어트리뷰트(Attribute) Conditional, Obsolete, DllImport 사용자정의 Attribute작성어트리뷰트(Attribute)Conditional, Obsolete, DllImport사용자정의 Attribute작성C# 어트리뷰트(Attribute)Attribute는 코드에 부가적

ojc.asia

https://www.youtube.com/watch?v=QXyOvFGp-rE&list=PLxU-iZCqT52DJyR6gqJy0MCL8RiTVXdos&index=16 





어트리뷰트(Attribute)

Conditional, Obsolete, DllImport

사용자정의 Attribute작성 





C# 어트리뷰트(Attribute)


  • Attribute는 코드에 부가적인 정보(메타 데이터)를 기록하고 읽을 수 있는 기술이다. 


  • 어트리뷰트는 클래스안에 메타정보를 포함시킬 수 있는 기술로써 클래스, 데이터 구조, 열거자 그리고 어셈블리와 같은 프로그래밍적 요소들의 실행 시 행동에 대한 정보를 기술할 수 있다. 


  • 다음과 같은 프로그래밍 요소에 대해 Attribute를 사용 할 수 있다. 

어셈블리, 모듈, 클래스, 구조체, 열거형 변수, 생성자, 메소드, 프로퍼티, 필드, 이벤트, 인터페이스, 파라미터, 반환 값, 델리게이트


  • 어트리뷰트 역시 클래스의 일종이며, Attribute 문법은 다음과 같다.

      [Attribute이름(positional_parameter, name_parameter = value, …) ]


  • 파라미터에는 두 종류가 있는데 첫번째는 위치지정 파라미터로 반드시 입력되어져야 하는데 어트리뷰트 클래스내 생성자의 인자 이므로 필수 파라미터 이다. 명명파라미터(name_parameter)는 꼭 필요하지는 않다. 어트리뷰트 안에 추가적인 정보를 넣을 때 이용한다.


[AdditionalInfo(“2004-01-01”)]  ( = [AdditionalInfoAttribute(“2004-01-01”)] )

public class Test { ..}


원하는 프로그래밍 요소 위에 Attribute를 사용하면 된다.


Conditional Attribute


C# 디버깅을 지원하기 위해 Conditional Attribute를 사용 할 수 있다. Conditional Attribute는 사용자가 정의한 값에 의해서 해당 메소드를 실행하도록 한다. 메소드 위만 붙일 수 있다.


Conditional Attribute는 클래스나 구조체 안에 있는 메소드에서만 사용 할 수 있다. 또 그 메소드는 void형 이어야 한다. 


#define SOUNDCARD 

#define SPEAKER


using System;

using System.Diagnostics;


class Test 

{

[Conditional ("SOUNDCARD")]

static void isSound() { isSpeaker(); }


[Conditional ("SPEAKER")]

static void isSpeaker() {

Console.WriteLine("음악을 들을 수 있습니다...");

}


static void Main() 

{

isSound();

}

}



Obsolete Attribute


C# 디버깅을 지원하기 위해 Obsolete Attribute를 사용 할 수 있다. 더 이상 사용하지 않는 클래스, 함수, 필드 앞에 Obsolete Attribute를 붙이면 된다. 이렇게 하면 해당 메소드를 호출할 때 더 이상 사용하지 않는 메소드라는 경고 메시지가 뜬다.


class ObsoleteTest

{

    [Obsolete]  //사용되지 않는다는 경고 메시지 출력

    public void OldMethod1() { }


    [Obsolete("추가메시지")] //사용되지 않는다는 경고 메시지 + 추가메시지 출력

    public void OldMethod2() { }


    //더이상 사용하지 않는다는 경고 메시지 + 추가메시지 출력 후 true면 컴파일 오류로 컴파일 오류

    [Obsolete("추가메시지", true)] 

    public void OldMethod3() { }

}

class Test

{

    static void Main()

    {

        ObsoleteTest o = new ObsoleteTest();

        o.OldMethod1();  //초록색 밑줄과 함께 사용되지 않는다는 경고 메시지 출력

        o.OldMethod2();  //초록색 밑줄과 함께 사용되지 않는다는 경고 메시지 + 추가메시지 출력

        o.OldMethod3();   //붉은색 밑줄과 함께 사용되지 않는다는 경고 메시지 + 추가메시지 출력, 컴파일불가

    }

}






DllImport Attribute


DllImport Attribute는 C#안에서 “Unmanaged Code”를 사용 할 수 있게 한다. Unmanaged Code란 닷넷 환경 밖에서 개발된 코드를 가리킨다. DllImport Attribute는 System.Runtime.InteropServices 네임스페이스 안에 정의되어 있다. 사용방법은 위치지정 파라미터로 사용할 DLL 파일을 인자로 넘겨 주면 된다.


using System.Runtime.InteropServices;


class Test 

{

//User32.dll 파일안의 MessageBox 함수를 불러와서 사용하는 예이다. 

          //DllImport Attribute를 이용하여 사용할 코드가 포함되어 있는 DLL을 넘겨주고

          // extern 키워드를 통해 사용하려고 하는 메소드가 외부에 있음을 알린다. 

          //이렇게 하면 닷넷 환경 밖에서 개발된 코드들도 C#안에서 쓸 수 있다.

[DllImport("User32.Dll")]

public static extern int MessageBox(int h, string m, string c, int type);


static void Main() { MessageBox(0, "Hello!", "In C#", 0); }

}


사용자 정의 어트리뷰트(Custom Attribute)의 정의


  • 어트리뷰트의 범위 지정


앞에서 Conditional Attribte는 메소드에만 붙일 수 있다고 했다. 그렇다면 사용자가 만든 어트리뷰트에 대해 특정한 곳에만 붙일 수 있게 하는 방법은 없을까? AttributeUsage를 이용해서 사용자가 정의한 데이터 형에만 어트리뷰트를 붙일 수 있다.


[AttributeUsage(AttrbuteTargets.Method)]
public class AdditionalInfoAttribute : System.Attribute { … }


AttributeUsage 역시 Attrbute 이며 사용자가 정의할 어트리뷰트 앞에 사용됨으로써 범위를 지정 할 수 있다. Method 이외에 AttrbuteTargets.Class, AttrbuteTargets.Delegate, AttrbuteTargets.Interface, AttrbuteTargets.Property, AttrbuteTargets.Constructor 등을 사용 할 수 있다.


만약 여러 개의 데이터 형에 붙이려면 ‘|’를 이용하면 된다.


[AttributeUsage(AttrbuteTargets.Method | AttrbuteTargets.Delegate)]

public class AdditionalInfoAttribute : Attribute { … }


또한 모든 데이터 형에 붙이는 것을 가능하게 하려면 AttrbuteTargets.All 이라고 해 주면 된다.


  • 어트리뷰트 클래스 선언


간단히 클래스에 대한 제작자, 최신 버전을 다운 받을 수 있는 곳 등의 정보를 담을 수 있는 어트리뷰트를 만들어 보도록 하겠다. 다른 클래스를 만드는 것처럼 비슷하게 클래스를 작성하면 어트리뷰트가 구현된다. 모든 어트리뷰트는 System.Attribute로 부터 상속받는다. 즉 보통 클래스를 선언하는 것과  같은 방법으로 선언하고 다만 System.Attribute로부터 상속을 받으면 그 클래스가 어트리뷰트가 되는 것이다. 일반 클래스와 구분하기 위해 접미사로 ‘Attribute’를 붙일 것을 권고한다.


어트리뷰트도 클래스이므로 생성자가 존재한다. 다만 어트리뷰트는 하나의 생성자만 가질 수 있다. 즉 생성자 오버로딩이 불가능하다. 그럼 추가로 받아야 하는 정보들은 어떻게 처리할까? 어트리뷰트에서는 생성자에서 꼭 집어 넣어야 하는 데이터는 위치지정 파라미터로 받고 부가적인 데이터는 명명 파라미터를 통해 받아들임으로써 문제를 해결 한다.


[사용자 정의 어트리뷰트 예제]

using System;

namespace AttrTest

{

    [AttributeUsage(AttributeTargets.Class)]

    public class AdditionalInfoAttribute : Attribute

    {


        //생성자에 있는 하나의 인자는 위치지정 파라미터 이다.

        //위치지정 파라미터는 클래스에 어트리뷰트를 붙일때 반드시 넘겨 줘야 한다.

        public AdditionalInfoAttribute(string name) =>  Name = name;


        public string Name

        {

            get; private set;

        }

        public string Download 

        {

            get; set;

        }

    }


    [AdditionalInfoAttribute("오라클자바커뮤니티", Download = "http://ojc.asia")]

    class Test { }


    class AttributeTest

    {

        static void Main()

        {

            Type type = typeof(Test);

            foreach (Attribute attr in type.GetCustomAttributes(true))

            {

                AdditionalInfoAttribute info = attr as AdditionalInfoAttribute;

                if (info != null)

                    Console.WriteLine("Name={0},Download ={1}",

                        info.Name,info.Download);

            }

        }

    }

}



Name=오라클자바커뮤니티,Download =http://ojc.asia


// 아래의 경우처럼 위치지정 파라미터는 생성자에 값을 그대로 전달하지만 명명 파라미터는 파라미터 이름에 값을 대입하여 생성자에 넘겨야 한다.

[AdditionalInfoAttribute(“jclee”,’2018-01-01”, Download = “http://ojc.asia”)]

class Test { … }


#어트리뷰트, #닷넷어트리뷰트, #닷넷동영상, #시샵교육, #시샵학원, #Attribute, #DllImport, #Conditioanl, #Obsolete, #시샵학원, #시샵동영상,  


어트리뷰트, 닷넷어트리뷰트, 닷넷동영상, 시샵교육, 시샵학원, Attribute, DllImport, Conditioanl, Obsolete, 시샵학원, 시샵동영상, 

C# 인덱서(Indexer), C#동영상교육, C#학원, 닷넷교육, 닷넷학원, C#동영상

 C# 인덱서(Indexer), C#동영상교육, C#학원, 닷넷교육, 닷넷학원, C#동영상


http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=404 


C# 인덱서(Indexer), C#동영상교육, C#학원

C# 인덱서(Indexer), C#동영상교육, C#학원인덱서(Indexer)실습 : VS 2022C# 인덱서(Indexer)일반적으로 C#의 속성(프로퍼티)를 이용하여 내부 필드(멤버 변수)에 접근하는데, 클래스 내부의 컬렉션 형태의 데

ojc.asia


https://www.youtube.com/watch?v=RWrdG2lfnBA&list=PLxU-iZCqT52DJyR6gqJy0MCL8RiTVXdos&index=15 






인덱서

(Indexer)


실습 : VS 2022





C# 인덱서(Indexer)


일반적으로 C#의 속성(프로퍼티)를 이용하여 내부 필드(멤버 변수)에 접근하는데, 클래스 내부의 컬렉션 형태의 데이터에 접근할 때는 인덱서(Indexer)를 주로 사용한다.


인덱서(Indexer)

❶ 이름이 this인 프로퍼티( public string this[int i] { … } )
❷ 인덱스(첨자)를 이용하여 객체 내의 데이터에 접근하게 해주는 속성(프로퍼티). 
❸ 객체를 배열처럼 접근할 수 있는 방법을 제공하는데, this[ ]를 사용하여 객체내부의 특정 필드(주로 컬렉션 형태의 자료)에 접근
❹ 사용법이 배열과 비슷하다는 의미이지 실제로 객체를 배열로 쓴다는 의미는 아니다.
❺ this[ ] 형태로 속성처럼 get, set을 정의하여 작성하는데 get 접근자는 값을 반환하고 set 접근자는 value키워드로 입력되는 값을 할당하며, this 키워드는 인덱서를 정의하는데 사용한다.
❻ [ ] 안에는 인덱싱을 위한 첨자가 들어오는데 int, string등 다양한 형태가 가능하다.


인덱서와 프로퍼티의 비교


프로퍼티가 이름을 통해 객체 내의 데이터에 접근하게 해 준다면 인덱서는 인덱스를 통해 객체 내의 데이터에 접근하게 해 준다. 인덱서는 get, set 접근자를 통해 어떤 필드의 값을 얻어 오거나 어떤 계산을 통해 새로운 값을 다른 곳에 지정한다. 인덱서 역시 프로퍼티처럼 실제 값을 가지고 있지 않기 때문에 ref, out과 같은 접근자를 사용할 수 없다. 물론 둘 다 void는 사용할 수 없다. 


System.String 클래스에 잠시 살펴보자.



string s = “Hello”;
char c = s[0];   //c = ‘H’, 객체를 배열처럼 다룸.


s가 배열이 아님에도 불구하고 배열처럼 사용하고 있다. 이것은 String 클래스가 인덱서로 구현되어 있기 때문에 가능한 것이다. 인덱서를 사용하면 string 타입처럼 객체를 배열처럼 쓰는 것이 가능해 진다는 것이다.


s[2] = ‘c’; //에러


이 경우 오류가 발생 하는 것은 String 인덱서가 읽기 전용, get만 만들어졌기 때문이며 인덱서를 이용하면 r-value 이든 l-value 이든지 상관없이 배열처럼 이용할 수 있다.


인덱서(Indexer) 와 배열(Array)의 비교


  1. 인덱서는 배열의 표기법과 비슷하다. 하지만 배열은 integer 형으로만 첨자를 사용할 수 있지만 인덱서인 경우엔 다른 타입도 첨자로 사용 가능하다.


class test {

public string this[string index]

{

get {…}

set {…}

}

}


  1. 또한 인덱서는 오버로딩이 가능하다. 여러 개의 인덱서를 선언해 놓고 그곳의 인자가 다르면 오버로딩 된다.


class test {

public string this[int number] { }

public string this[int number, string name] {}

}




[예제1 인덱서 심플 예제]

namespace IndexerTest

{

    class Dept

    {

        public string[] emps = new string[3];

        public string this[int i]

        {

            get { return emps[i];  }    //r-value

            set { emps[i] = value; }  //l=value

        }

    }

    class Test

    {

        static void Main()

        {

            Dept d1 = new Dept();

            d1.emps[0] = "사원1"; d1.emps[1] = "사원2"; d1.emps[2] = "사원3";

            Console.WriteLine("d1.emps[0] : {0}", d1.emps[0]);


            d1[0] = "사원1"; d1[1] = "사원2"; d1[2] = "사원3";

            Console.WriteLine("d1.emps[0] : {0}", d1[0]);


        }

    }

}



[예제2 : 문자열을 첨자로 사용한 인덱서 예제]

class DayCollection

{

    string[] days = { "일", "월", "화", "수", "목", "금", "토" };

    private int GetDay(string testDay)

    {

        for (int j = 0; j < days.Length; j++)

        {

            if (days[j] == testDay) { return j; }

        }

        return 999;

    }


    public int this[string day]

    {

        get { return (GetDay(day)); }

    }

}

class Program

{

    static void Main(string[] args)

    {

        DayCollection week = new DayCollection();

        System.Console.WriteLine(week["일"]);   //0

        // 999 리턴        

        System.Console.WriteLine(week["없는요일"]);

    }

}



[예제3 : 일반화 프로그래밍을 이용한 인덱서 예제]


class Ojc<T>   //일반화 클래스 정의

{

    //외부에서 접근못하도록 private으로 배열을 정의하고

    //배열의 값은 인덱스를 통해 다루도록 한다.

    //배열의 타입은 Ojc를 사용하는 시점에 정의 ==> Generic

    private T[] ojcArr = new T[10];


    //Generic을 이용하여 인덱서를 정의하자.

    public T this[int i]

    {

        get   //R-VALUE

        {

            return ojcArr[i];

        }

        set   //L-VALUE

        {

            ojcArr[i] = value;

        }


       // C#7.0 이상

        /* get  => ojcArr[i];

        set   => ojcArr[i] = value; */


    }

}


class Program

{

    static void Main(string[] args)

    {

        Ojc<string> ojc1 = new Ojc<string>();

        ojc1[0] = "Hello, OJC";

        string s = ojc1[0];

        Console.WriteLine(s); ;


        Ojc<int> ojc2 = new Ojc<int>();

        ojc2[0] = 999;

        Console.WriteLine(ojc2[0]);

    }

}



[결과]

Hello, OJC

999



#인덱서, #Indexer, #시샵교육, #시샵학원, #시샵인덱서, #닷넷교육, #닷넷학원, #닷넷동영상, #시샵동영상, 인덱서, Indexer, 시샵교육, 시샵학원, 시샵인덱서, 닷넷교육, 닷넷학원, 닷넷동영상, 시샵동영상,  

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...