C# 28

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

C# 속성 (Property) - 1. 속성, 매개변수 없는 속성

속성 (property) 속성은 메서드를 소스 코드상에서 호출하는 방법을 단순하게 만들어준다. CLR은 흔히 속성이라고 이야기하는 매개변수 없는 속성과 매개변수가 있는 속성 (C#에서는 인덱서)를 지원한다. 매개변수 없는 속성 객체지향에서 중요한건 데이터 캡슐화이다. 클래스에서 정의한 필드가 외부에 노출되지 않도록 하여 필드의 상태 보호하는 것이다. 예를 들어, Person p = new Person(); p.Age = -1; //나이가 음수? 위와 같은 코드는 쉽게 필드의 상태를 훼손시킨다. 뿐만 아니라, 값을 캐쉬에 보관하거나, 내부 객체를 지연생성 하거나 쓰레드 안정적으로 접근해야 하는 경우에도 데이터 캡슐화를 하는게 중요할 수 있다. 따라서 타입을 설계할 때는 모든 필드를 가능한 private으로..

언어/C# 2020.12.20

C# 매개변수

선택된 매개변수와 명명된 매개변수 메서드의 매개변수를 정할 때 일부 또는 전체에 대해 기본값을 정할 수 있다. public static void M(int a = 1, int b = 2, int c = 3) { } public static void Main() { M(); //M(1,2,3) M(1, c: 2, b: 1); // 콜론(:) 을 이용해서 값을 전할 매개변수를 고를 수 있다. } 호출 시점에 매개변수를 생략하면 ,C# 컴파일러는 매개변수의 기본값을 포함하는 코드를 생성한다. 모듈 외부에서 불리는 메서드의 경우 기본값을 바꾸는건 위험할 수 있는데, 만약 매개변수의 기본값을 바꾼 경우 호출하는 쪽의 코드도 다시 컴파일 하지 않으면 예전의 기본값을 가진 메서드를 호출하기 때문이다. 따라서 publ..

언어/C# 2020.12.13