언어 54

C# 사용자 정의 특성

이전 글 tsyang.tistory.com/3 Attribute 0. 개요 애트리뷰트(attribute)는 다양한 요소(클래스, 메서드, 필드... 등)에 메타데이터를 추가할 수 있게 해 준다. 1. 필요성 두 가지 팝업 창이 존재한다. 한 가지는 자주 팝업 되고(ex. 이벤트 창) tsyang.tistory.com 이 글에서는 좀더 자세히 작성 사용자 정의 특성의 사용 일반 사용자 정의 특성은 단순히 특정 대상에 대해 추가적인 정보를 부가한다. 구체적으로도 컴파일러가 관리 모듈의 메타데이터상에 추가 정보를 기입하는 것에 불과하다. 또한 사용자 정의 특성은 단순히 특정 타입의 인스턴스이다. 모든 사용자 정의 특성은 직 간접적으로 모두 public 추상 클래스인 System.Attribute 클래스로부터 ..

언어/C# 2021.02.28

C# - 델리게이트

.NET Framwork는 콜백 함수 메커니즘을 델리게이트라는 형태로 노출한다. 델리게이트는 타입 안정성을 보장함으로써 C++등 다른 언어의 콜백 메커니즘은 다르게 더 강력한 기능을 제안한다. (그만큼 성능은 떨어질수도) 델리게이트 네이티브 C/C++에서 비멤버 함수의 주소는 단지 메모리 주소일 뿐이다. 이 주소는 다른 정보(매개변수, 반환 타입, 호출 규칙 등)를 일절 포함하지 않는다. 결국 타입 안정성이 없다. (대신 가볍고 빠르게 동작한다.) .NET Framework는 델리게이트라는 타입 안정성을 준수하는 메커니즘을 제공한다. 델리게이트 정의 delegate void SomeDel(int value); public class Program { public static void Main() { St..

언어/C# 2021.02.21

C# - 배열

선요약 Array.Copy로 값타입의 배열도 캐스팅 할 수 있다. 모든 배열은 암묵적으로 IEnumerable, ICollection, IList를 구현한다. 또한 IEnumerable, ICollection, IList도 구현하며 참조 타입의 경우 T의 상위 타입까지 구현한다. (값 타입은 T만) 데이터가 없는 배열을 반환하거나 필드에 정의하는 경우에는 null보다는 빈 배열을 참조하도록 하는게 좋다. (프로그래머의 예외처리를 줄여준다.) 다차원 배열보다는 중첩 배열이나 1차원 배열이 더 빠르다. 배열 모든 배열은 System.Array 타입을 상속한다. CLR에서는 1차원 배열, 다차원 배열, 중첩 배열을 지원한다. int[,] darr = new int[5, 10]; //다차원 배열 int[][] ..

언어/C# 2021.02.10

C# - 문자열 - 1

책에는 문화권 및 암호화 관련된 내용이 있지만, 나중에 시간나면 정리하기로 함 System.String C#의 String은 참조 타입이다. 따라서 String 타입과 그 내부의 배열은 항상 힙에 할당된다. 또한 변경이 불가능하다. C++ 처럼 특정 문자만 수정하는 등의 행동을 할 수 없다. (StringBuilder를 쓰면 되지만) string s = "Hi" + " " + "there."; 또 위처럼 리터럴로 이뤄진 문자들은 컴파일 시점에 모든 문자열들을 연결하여 하나의 단일 문자열인 "Hi there."로 합한다. 따라서 Stringbuilder를 쓰지 않아도 임시 문자열이 생성되지 않는다. 줄 바꿈의 경우에는 System.Environment.NewLine을 써주는게 좋다. string a = "..

언어/C# 2021.02.02

C# 인터페이스

선요약 인터페이스는 제너릭 버전 써라. 명시적 인터페이스 구현은 웬만하면 쓰지 마라. (써야할 때도 있지만...) 박싱과 타입 안정성에 주의하자. (인터페이스는 참조형이다.) IS-A, CAN-DO 관계로 타입과 인터페이스를 골라라.. 애매하다면 타입이 확장성과 수정이 더 용이하다는 점을 염두에 둔다. 인터페이스 상속하기 C# 컴파일러는 인터페이스 메서드를 구현할 때 public으로 선언하도록 요구한다. CLR은 인터페이스가 virtual로 정의될 것을 요구한다. 만약 소스 코드에서 메서드를 구현할 때 명시적으로 virtual 키워드를 지정하지 않으면 컴파일러가 해당 메서드에 virtual 키워드와 sealed 키워드를 포함시킨다. 이 경우 자식 클래스에서 인터페이스 메서드를 재정의할 수 없다. 만약 명..

언어/C# 2021.01.27

C# 제너릭 - 3

검증 가능성과 제약조건 public static bool Min(T o1, T o2) { if (o1.CompareTo(o2) < 0) return o1; else return o2; } 위와같은 제너릭 메서드는 문제가 있다. T==0 으로 비교하는 과정에서 o1과 o2가 compareTo를 사용할 수 있는 타입인지 알 수 없기 때문이다. 따라서 CLR 은 제약조건이라는걸 제공해줘서 타입의 종류를 제한할 수 있게 해준다. public static T Min(T o1, T o2) where T : IComparable { if (o1.CompareTo(o2) < 0) return o1; else return o2; } 위처럼 where 토큰을 이용하여 T를 IComparable 인터페이스를 구현한 타입으로..

언어/C# 2021.01.20

C# - 제네릭 2

공변성과 반공변성 (델리게이트, 인터페이스) 델리게이트의 제네릭 타입 매개변수들에 공변성(Covariant)과 반공변성(Contra-Variant)의 성질을 나타낼 수 있다. 이런 기능일 이용하면 제네릭의 타입 인자가 달라도, 특정 제네릭 델리게이트 타입의 변수를 이와 호환되는 다른 델리게이트 타입으로 캐스팅할 수 있다. 제네릭 타입 매개변수는 다음 중 하나가 될 수 있다. 고정(Invariant) : 제네릭 타입 매개변수는 변경될 수 없음 반공변성 : 제네릭 타입 매개변수로 지정한 타입을 해당 타입을 상속한 (하위타입) 타입으로 변경할 수 있음. C#에서는 in 키워드를 사용. 입력 용도로 사용되는 인스턴스에 대해서만 적용 공변성 : 제네릭 타입 매개변수로 지정한 타입을 해당 타입이 상속한 (상위타입)..

언어/C# 2021.01.18

C# 제너릭 - 1

일반 제너릭 타입이나 메서드를 정의할 때 ,를 붙여 데이터 타입을 지정하지 않고도 동작할 수 있음을 나타내는데 이 때 T와 같이 데이터 타입으로 지정하는 변수를 타입 매개변수라고 한다. 또한 제네릭 타입이나 메서드를 사용할 때, 지정하는 데이터 타입을 타입 인자라고 한다. 마이크로소프트의 디자인 가이드라인에 따르면 제네릭 매개변수는 첫 글자를 대문자로 시작하고 접두사로 T를 붙인다. (TValue, TKey...) 제네릭이 개발자들에게 제공하는 이점은 다음과 같다. 소스 코드 보호 : 제네릭 알고리즘을 사용하기 위해 알고리즘을 구현하는 소스 코드가 반드시 필요하지는 않다. (먼소리지) 타입 안정성 : 지정된 타입과 호환하는 타입에 대해서만 사용할 수 있도록 한다. 그렇지 않으면 컴파일 에러가 발생한다. ..

언어/C# 2021.01.09

C# 이벤트

이벤트 설계 1. 이벤트 리스너들에게 보내는 정보 타입을 정의하기 보통 리스너들에게 보낼 정보들은 단일 클래스로 캡슐화 되며 private 필드와 이 필드들에 대한 읽기 전용 속성들을 포함한다. 편의상 이런 정보를 전달용 클래스는 System.EventArgs 타입을 상속한 타입으로 정의하는게 일반적이다. 또 이름에도 EventArgs라는 접미사를 관습적으로 붙인다. // 정보 전달용 클래스 public sealed class NewMailEventArgs : EventArgs { private readonly string m_from, m_to; public NewMailEventArgs(string from, string to) { m_from = from; m_to = to; } public str..

언어/C# 2021.01.02

C# 속성 (Property) - 2

익명 타입 var anon = new { Name = "Yang", Year = 1993 }; Console.WriteLine($"Name : {anon.Name}, Year = {anon.Year}"); 위와 같은 방법으로 익명 타입을 생성할 수 있다. 저렇게 익명 타입을 생성하면 컴파일러가 알아서 이름을 붙여주며, var을 이용해서 타입을 유추할 수 있게 된다. 컴파일러가 하는 일을 더 자세히 보면, 각각의 표현식으로 부터 정확한 타입을 유추하여 private readonly 필드를 만들고, 각각의 속성을 정의하며 주어진 값들을 받을 수 있는 생성자를 정의한다. 추가적으로 Equals, GetHashCode, ToString 메서드까지 제정의한다. 다음과 같이 이름을 유추하거나, 배열로도 사용할 수 ..

언어/C# 2020.12.27