언어/C# 46

C# - 리플렉션 (Reflection)

리플렉션 리플렉션은 컴파일 시에 알 수 없었던 타입이나 멤버들을 찾아내고 사용할 수 있게 해주는 메커니즘이다. 그러나 다음의 주요한 단점이 존재한다. 리플렉션을 사용하면 컴파일 시에 타입 안정성을 해친다. 리플렉션은 전반적으로 느리다. 어셈블리에서 정의하는 메타데이터를 살필 때 항상 문자열 검색이 수행되어야 한다. 리플렉션을 이용하여 멤버를 호출하면 성능에 좋지 않은 영향을 미친다. 따라서 먼저 매개변수들을 배열로 포장해야 한다. 내부적으로는 이렇게 포장된 내용을 다시 꺼내어 스레드의 스택에 옮긴다. 추가적으로 CLR이 메서드 호출 전에 각각의 매개변수들이 올바른 타입을 가지고 있는지 확인하고 호출자가 호출하려는 멤버에 접근할 보한 권한이 있는지 확인해야 한다. 상기의 이유로, 타입의 필드나 메서드 혹은..

언어/C# 2021.07.04

C# - CLR 호스팅과 앱도메인

호스팅 & 앱도메인 호스팅이란? 어떤 응용프로그램에서도 CLR을 사용할 수 있도록 해주는 기능이다. 이 기능을 이용하면 기존에 개발된 응용프로그램에 추가 기능을 관리 코드를 이용해 작성할 수 있다. 그러나 이런 확장은 위험의 여지가 있는데, 제 3자의 DLL을 프로세스 공간에 로드함으로써 DLL이 응용 프로그램의 데이터나 코드를 손상시키거나 접근할 수 없는 리소스에 접근(보안 컨텍스트 취득)할 수 있기 때문이다. 이를 해결하기 위해 앱도메인 기능이 있다. 앱도메인은 제 3자의 코드를 프로세스에 로드할 수 있게 해주지만 데이터나 코드 및 보안 컨텍스트가 손상되거나 탈취되지 않도록 보장해준다. 호스팅과 앱도메인 기능을 어셈블리 로딩과 리플렉션과 사용하면 .NET Framework의 참맛을 알 수 있다고 한다..

언어/C# 2021.06.27

C# - 관리 힙과 GC (2)

네이티브 리소스의 처리 네이티브 리소스 네이티브 리소스란 파일이나 커널 객체 같은 걸 말한다. 대부분의 타입들은 메모리만을 이용하지만 네이티브 리소스를 사용하는 애들(파일 핸들, 소켓) 같은 애들은 그렇지 않다. 이런 경우에 GC가 네이티브 리소스를 감싸고 있는 타입을 수거해 간다면 네이티브 리소스에 대한 누수가 발생하게 된다!! GC는 네이티브 리소스에 대해 알지 못하기 때문에 이에 대한 처리가 필요해 보인다. Finalization 파일, 네트워크 연결, 소켓, 뮤텍스 같은 네이티브 리소스를 감싸고 있는 타입은 finalization이란걸 지원한다. CLR은 GC가 이런 객체를 가비지 수집하는 과정에서 Finalize 라는 메서드를 호출하여 객체가 감싸는 네이티브 리소스를 정리할 기회를 준다. pub..

언어/C# 2021.04.03

C# - 관리 힙과 GC (1)

관리 힙 C#은 왜 관리 힙을 쓰나? 메모리 관리를 수동으로 해줘야 하는 C++의 경우 메모리 해제를 까먹어 메모리 누수가 발생하거나, 이미 해제한 메모리에 접근하여 메모리 손상이 발생하는 경우가 많고 이는 결국 버그나 보안 취약점으로 연결된다. 리소스 할당 CLR환경 하에서는 모든 객체가 관리 힙에 할당된다. 프로세스가 초기화되면, CLR은 관리 힙으로 쓸 주소 공간을 할당하고 다음 객체를 할당할 위치를 가리키는 포인터(이하 NextObjPtr)을 시작 주소를 가리키게 한다. 이 주소 영역이 가득 차면 CLR은 프로세스의 주소 공간이 사용될 때 까지 영역을 확대한다. new연산자 CLR에서 new연산자는, 필요한 용량을 계산한다. (특정 타입의 필드, 상속한 타입의 필드까지) - 여기에는 type ob..

언어/C# 2021.03.28

C# Nullable, Null 결합 연산자

Nullable CLR의 값 타입은 null을 가질 수 없다. 그러나 여러 이유로 값 타입이 null을 가져야 할 때가 있다. 이에 대비하기 위해 CLR은 null을 허용하는 값 타입을 지원한다. FCL에는 System.Nullable 구조체가 정의되어 있다. (여러 이유 : 데이터베이스에서는 32비트 정수 값이 null을 가질 수 있음, Java의 Date클래스는 참조 타입이어서 null을 가질 수 있음 그러나 C#은 그렇지 않음... 등) Nullable에서 T는 구조체여야 하며 Nullable에는 여기에 현재 값을 가지고 있는지에대한 Boolean필드 정도만 추가한 값 타입이다. int? 는 Nullable와 같은 의미이다. Nullable의 박싱/ 언박싱 Nullable 타입은 값 타입이기에 박싱..

언어/C# 2021.03.06

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