프로그래밍 언어/C#

    [C#] 람다식 (Lambda Expression)

    람다식(Lambda)식은 접근자, 함수 이름, return문이 없는 익명 함수(anonymous function)다. 람다식을 사용하면 더 짧은 코드를 작성할 수 있으며 => 연산자를 사용한다. class Program { static int DoubleFunc(int num) { return num * 2; } static void Main(string[] args) { Console.WriteLine(DoubleFunc(10)); } } // 람다식 사용 class Program { static void Main(string[] args) { Func DoubleFunc = (num) => num * 2; int num = 10; Console.WriteLine(DoubleFunc(num)); } }..

    [C#] 배열의 타입을 변경하는 방법 (제네릭 가능)

    1. Array 클래스의 ConvertAll 메서드 public static TOutput[] ConvertAll ( TInput[] array, Converter converter); TInput[] array - 특정 타입으로 변환하고 싶은 배열을 전달한다. Convert converter - 배열의 요소를 특정 타입으로 변환하는 변환기를 전달한다. - TInput: 기존 배열의 타입을 설정한다. - TOutput: 변환하고 싶은 타입을 설정한다. ConvertAll() 메서드는 특정 타입으로 변환된 새로운 배열을 반환한다. 다음 예제는 string 타입의 배열을 int 타입의 배열로 변환된 새로운 배열을 반환한다 class Program { public static int stringToInt(st..

    [C#] String Interning

    C#의 string.Intern 이라는 메서드는 문자열 풀에서 문자열을 풀링시켜 메모리를 아끼고 메모리 비교를 더 빠르게 해준다. 쓰는건 정말 간단하다. a = string.Intern("this is string") 으로 문자열을 넘기면 끝이다. 간단하게 퍼포먼스 비교를 해보자. string a = "dolphin"; string b = "dol"; b += "phin"; bool res = false; var sw = new Stopwatch(); sw.Start(); for (int i = 0; i < 100000000; i++) res = a == b; sw.Stop(); Console.WriteLine("Before intern:"); Console.WriteLine(sw.ElapsedMilli..

    [C#] 고성능 서버 - __FILE__, __LINE__ 대체제

    UI가 없는 서버에서 동작의 내용을 확인하는 가장 기본적인 방법은 file로 남기는 log다. 정상 동작이나 오류상황에 대한 상세한 로그가 남아야 문제가 생겼을 때 파악하기가 쉽기 때문에, 간단한 동작이지만 아주 빈번하게 호출되는 부분이다. 로그 출력에서 성능을 많이 빼앗기지 않도록 기반을 다져놓으면 비즈니스 로직 구현을 위해 더 많은 H/W 리소스를 배분할 수 있다. 성능을 굳이 신경쓰지 않는다면 아래 있는 내용을 끝까지 모두 적용할 필요는 없다. 콜스택을 얻어와서 가장 마지막 함수를 찍는 방법 현재 스레드 컨텍스트에서의 StackFrame 정보를 얻어온 후, 프레임 데이터의 가장 마지막 부분을 읽어 호출자의 정보를 얻어낼 수 있다. 가장 태초부터 있었던 방법이기 때문에 C#으로 함수 호출 위치를 얻어..

    [C#] 8.0 새로운 기능

    1. 디폴트 인터페이스 멤버(Default Inteface Members) 이전 버전에서는 인터페이스를 한번 배포한 후 수정하면, 기존에 구현된 모든 타입들을 수정하지 않는 한 타입 오류를 발생시켰다. 더구나 그 인터페이스를 외부에서 사용한다면, 수정은 거의 불가능하였다. C# 8.0에서는 인터페이스에 새로운 멤버를 추가하고 새로운 멤버의 Body 구현 부분을 추가할 수 있게 되었다. 이렇게 새로 추가된 인터페이스 멤버는 디폴트로 사용되기 때문에 기존 구현된 타입들이 새 멤버를 추가적으로 구현되지 않을 경우 이 디폴트 구현을 사용하게 된다. 새로 구현하는 클래스는 디폴트 멤버 구현을 사용하지 않고 재정의할 수 있다. 인터페이스의 디폴트 멤버 구현을 액세스 하기 위해서는 인터페이스로 캐스팅된 변수를 사용해..

    [C#] 9.0 새로운 기능

    C# 9.0 추가된 기능들 최상위 프로그램(Top-Level Programs) init accessor record Type 향상된 패턴 매칭(Pattern matching) 최상위 프로그램 (Top-Level Programs) 1. 정의 C# 프로그램은 Main() 정적 메서드에서부터 프로그램 시작하며, C# 프로젝트 생성하면 항상 이 Main() 메서드를 자동으로 생성한다. 프로그래밍에서 이를 보통 엔트리 포인트(Entry point) 라 부른다. 프로그래밍을 처음 시작하면 Main() 엔트리 포인트 부분의 이해가 어렵기 때문에 C# 9.0에서 이러한 제약을 없애고 바로 C# 문장을 사용할 수 있는 기능을 제공한다. 이를 최상위 프로그램(Top-Level Program) 이라 부른다. 2. 사용 예제..

    [C#] 4.0 필수 매개변수 및 선택적 매개변수

    C# 4.0 필수 매개변수 및 선택적 매개변수 4.0에 새로 추가된 기능이라고 한다. 기존에는 매개변수가 1개 일 경우, 2개일 경우 어떤 매개변수를 이용하느냐에 따라 오버로딩 하면서 사용했다. 어떤 것을 예제로 사용할지 고민하다가 Account를 생성하는 부분을 코드로 짜기로 했다. Create라는 함수가 1. 이름, 2. 이름+폰번호, 3. 이름+폰번호+주소 이렇게 세가지 방법으로 인수를 넘겼을 때 동작하려면 우리는 아래의 코드처럼 오버로딩을 이용했다. [1] 기존의 오버로딩 기법 현재 AccountBook 클래스에는 Create라는 함수가 있는데 매개변수에 따라 재선언하여 오버로딩 해둔 것을 볼 수 있다. C#을 만나기 전까지는 나도 오버로딩을 하여 사용하기도 했고 함수명에 따라 구분하기도 했다. ..

    [C#] 생성자와 상속

    자식 클래스에서 부모클래스로 접근은 가능하지만 자식클래스에서 부모클래스의 생성자는 자동으로 상속되지 않는다. class Parent { public int X; public Parent() { } public Parent(int X) { this.X = X; } } class Child : Parent { } class Program { static void Main(string[] args) { Child child = new Child(123); //컴파일에러 Console.WriteLine(child.X); } } 자식클래스는 자신이 노출하고자 하는 생성자들을 반드시 '다시 정의' 해야한다. class Parent { public int X; public Parent() { } public Pare..

    [C#] 하나의 클래스의 모든 상속클래스 (자식클래스) 가져오기

    var listOfBs = ( from domainAssembly in AppDomain.CurrentDomain.GetAssemblies() // alternative: from domainAssembly in domainAssembly.GetExportedTypes() from type in domainAssembly.GetTypes() where typeof(B).IsAssignableFrom(type) // alternative: && type != typeof(B) // alternative: && ! type.IsAbstract // alternative: where type.IsSubclassOf(typeof(B)) select type).ToArray(); 다른 버전 var listOfBs..

    [C#] event (이벤트) 개념

    이벤트는 클래스내에 특정한 일(event)이 있어났음을 외부의 이벤트 가입자(subscriber)들에게 알려주는 기능을 한다. C#에서 이벤트는 event라는 키워드를 사용하여 표시하며, 클래스 내에서 일종의 필드처럼 정의된다. 이벤트에 가입하는 외부 가입자 측에서는 이벤트가 발생했을 때 어떤 명령들을 실행할 지를 지정해 주는데, 이를 이벤트 핸들러라 한다. 이벤트에 가입하기 위해서는 += 연산자를 사용하여 이벤트핸들러를 이벤트에 추가한다. 반대로 이벤트핸들러를 삭제하기 위해서는 -= 연산자를 사용한다. 하나의 이벤트에는 여러 개의 이벤트핸들러들을 추가할 수 있으며, 이벤트가 발생되면 추가된 이벤트핸들러들을 모두 차례로 호출한다. 다음 코드는 클래스(MyButton) 내에서 이벤트(Click)를 정의하고..