본문 바로가기

csharp33

LINQ SelectMany로 컬렉션 플래튼닝 LINQ SelectMany로 컬렉션 플래튼닝SelectMany는 컬렉션의 컬렉션을 단일 시퀀스로 변환하는 LINQ 메서드로, 중첩된 배열이나 리스트를 평탄화(flatten)하는 데 사용됩니다. 목적은 계층적 데이터 구조를 간단히 처리하여 쿼리를 효율적으로 만드는 것입니다. 복잡한 조인을 피하고 가독성을 높입니다. using System; using System.Collections.Generic; using System.Linq; public class LINQExample { public void FlattenNestedLists() { var nestedList = new List> { new List { "A1", "A2" },.. 2025. 9. 15.
델리게이트와 이벤트를 활용한 느슨한 결합 구현 델리게이트와 이벤트를 활용한 느슨한 결합 구현델리게이트는 메서드 시그니처를 나타내는 타입으로, 함수를 변수처럼 다루며 이벤트는 델리게이트를 기반으로 한 발행-구독 패턴입니다. 목적은 클래스 간 결합도를 낮추고, 확장성을 높이는 것입니다. 이벤트 핸들러를 등록하여 변경 사항을 알릴 때 유용합니다. using System; public class Publisher { // 델리게이트 정의 public delegate void NotificationHandler(string message); // 이벤트 선언 public event NotificationHandler OnNotification; public void Notify(string message) { .. 2025. 9. 11.
default 리터럴로 간결한 초기화 default 리터럴로 간결한 초기화C# 7.1부터 default 리터럴을 사용하면 값 타입이나 제네릭 타입을 간단히 초기화할 수 있습니다. 이전에는 default(T)처럼 타입을 명시해야 했지만, 이제는 default만 써도 컴파일러가 타입을 추론하여 기본값(숫자는 0, bool은 false, 참조형은 null 등)을 지정합니다. using System; class Program { static void PrintDefault() { // 제네릭 타입에 대해 간결하게 기본값 할당 T value = default; Console.WriteLine($"Type: {typeof(T)}, Default: {value}"); } st.. 2025. 9. 9.
stackalloc으로 고성능 메모리 할당 stackalloc으로 고성능 메모리 할당stackalloc 키워드는 힙 대신 스택 메모리에 고정 크기 배열을 직접 할당할 수 있게 해줍니다. 가비지 컬렉션 부담이 줄어들고, 빠른 메모리 접근이 가능하여 임시 버퍼, 문자열 처리, 고빈도 연산에서 성능을 크게 향상시킬 수 있습니다. using System; class Program { static void Main() { // 스택에 100개의 int 배열을 직접 할당 Span buffer = stackalloc int[100]; for (int i = 0; i { buffer[i] = i * 2; } Console.WriteLi.. 2025. 9. 5.
Memory<T>와 Span<T>로 안전한 메모리 관리 Memory와 Span로 안전한 메모리 관리 Span와 Memory는 배열, 문자열, 네이티브 메모리 등 연속된 메모리를 안전하고 효율적으로 다룰 수 있도록 지원합니다. Span는 스택 기반에서 빠르게 동작하며, Memory는 힙에서도 사용할 수 있고 비동기 코드에서도 안전하게 전달할 수 있습니다. using System; class Program { static void Main() { int[] numbers = { 10, 20, 30, 40, 50 }; // 배열 일부를 Span으로 슬라이스 Span slice = numbers.AsSpan(1, 3); foreach (var n in slice) { .. 2025. 9. 3.
ref readonly 반환으로 불필요한 복사 방지 ref readonly 반환으로 불필요한 복사 방지C# 7.2부터 ref readonly 반환을 사용하면 메서드가 값을 복사하지 않고 원본 데이터에 대한 읽기 전용 참조를 반환할 수 있습니다. 이 기능은 특히 구조체처럼 크기가 큰 값 타입을 다룰 때 성능 최적화에 효과적입니다. using System; struct BigStruct { public int A, B, C, D, E, F, G, H; } class DataContainer { private BigStruct[] data = new BigStruct[100]; public ref readonly BigStruct GetItem(int index) { return ref data[index]; //.. 2025. 9. 2.
readonly struct로 불변 값 타입 최적화 readonly struct로 불변 값 타입 최적화 C# 7.2부터 도입된 readonly struct는 구조체가 불변임을 보장하여, 값 복사 비용을 최소화하고 불변성을 유지할 수 있습니다. 특히 성능에 민감한 코드에서 안전하고 빠른 불변 값 타입을 정의할 때 유용합니다. using System; readonly struct Point { public int X { get; } public int Y { get; } public Point(int x, int y) { X = x; Y = y; } // 읽기 전용 메서드 - 값 타입 불변성 유지 public double Distance => Math.Sqrt(X * X + .. 2025. 9. 1.
async와 await로 비동기 프로그래밍 처리하기 async와 await로 비동기 프로그래밍 처리하기 C#의 async와 await 키워드는 비동기 프로그래밍을 단순화해줍니다. 복잡한 콜백 구조 없이도 직관적으로 비동기 작업을 작성할 수 있으며, 긴 실행 시간이 필요한 I/O 작업(파일 처리, DB 조회, API 호출 등)에서 UI 멈춤 현상을 방지하는 데 매우 효과적입니다. using System; using Systehttp://m.Net.Http;using Systehttp://m.Threading.Tasks;class Program { static async Task Main() { Console.WriteLine("데이터 요청 시작..."); string result = await GetDataA.. 2025. 8. 27.
nameof 연산자로 안전한 코드 작성 nameof 연산자로 안전한 코드 작성 nameof 연산자는 변수, 메서드, 클래스 등의 식별자 이름을 문자열로 가져오는 기능입니다. 하드코딩된 문자열 대신 nameof를 사용하면 리팩터링 시에도 안전하고, 코드의 유지보수성을 크게 높여줍니다. using System; class Person { public string Name { get; set; } } class Program { static void Main() { var person = new Person { Name = "Alice" }; // nameof 사용 전 Console.WriteLine("속성명: Name"); // nameof 사용 후 (안전한 방.. 2025. 8. 26.
Span<T>를 이용한 고성능 문자열 처리 Span를 이용한 고성능 문자열 처리 Span는 관리 힙을 할당하지 않고 연속된 메모리 영역을 안전하게 다룰 수 있게 해주는 구조체입니다. 문자열을 잘라 쓰거나 배열 일부만 처리할 때 복사 없이 접근할 수 있어 성능과 메모리 효율이 뛰어납니다. using System; class Program { static void Main() { string text = "Hello, World!"; // 문자열 일부를 잘라내기 (복사 없음) ReadOnlySpan span = text.AsSpan(7, 5); Console.WriteLine(span.ToString()); // World //.. 2025. 8. 12.
switch 표현식으로 깔끔한 조건 분기 처리 switch 표현식으로 깔끔한 조건 분기 처리 C# 8.0부터 도입된 switch 표현식은 기존 switch 문보다 더 간결하고 안전한 방식으로 조건 분기를 처리할 수 있게 해줍니다. 특히 enum, 튜플, 패턴 매칭 등과 함께 사용하면 코드의 가독성과 유지보수성이 크게 향상됩니다. enum UserRole { Admin, Manager, Guest } class Program { static void Main() { var role = UserRole.Manager; string access = role switch { UserRole.Admin => "모든 권한 허용", UserRole.Man.. 2025. 7. 25.
enum을 활용한 의미 있는 상수 집합 정의 enum을 활용한 의미 있는 상수 집합 정의 enum(열거형)은 관련된 상수 값을 이름으로 표현할 수 있게 해주는 C#의 기능입니다. 의미 있는 이름으로 코드를 작성하면 가독성, 유지보수성이 모두 좋아집니다. using System; enum OrderStatus { Pending, Processing, Shipped, Delivered, Cancelled } class Program { static void Main() { OrderStatus status = OrderStatus.Shipped; Console.WriteLine($"주문 상태: {status}"); if (status == OrderSta.. 2025. 4. 16.
string interpolation으로 문자열 조합 간결하게 하기 string interpolation으로 문자열 조합 간결하게 하기C#의 문자열 보간(String Interpolation) 기능을 사용하면 문자열을 더 간단하고 가독성 좋게 조합할 수 있습니다. 기존의 + 연산이나 string.Format()보다 더 직관적인 문법을 제공합니다. using System; class Program { static void Main() { string name = "홍길동"; int age = 21; string message = $"안녕하세요, 제 이름은 {name}이고 나이는 {age}살입니다."; Console.WriteLine(message); } } 출력 결과 안녕하세요, 제 이름은 홍.. 2025. 4. 15.
try-catch-finally 구문으로 예외 처리 완전 정복! try-catch-finally 구문으로 예외 처리 완전 정복! C#에서는 프로그램 실행 중 예외 상황이 발생할 수 있으며, 이를 try-catch-finally 구문으로 안전하게 처리할 수 있습니다. 오류를 잡고, 리소스를 정리하고, 사용자에게 친절한 메시지를 제공하는 것은 프로 개발자의 기본입니다! using System; class Program {     static void Main()     {         try         {             Console.Write("숫자를 입력하세요: ");             int number = int.Parse(Console.ReadLine());             Console.WriteLine($"입력한 숫자: {number}".. 2025. 4. 14.
Tuple을 활용한 다중 값 반환 Tuple을 활용한 다중 값 반환  C#에서는 Tuple을 사용하여 메서드에서 여러 값을 간단하게 반환할 수 있습니다. 클래스를 만들 필요 없이 깔끔한 반환 구조를 만들 수 있어 매우 유용합니다. using System; class Program {     static void Main()     {         var (sum, product) = Calculate(4, 5);         Console.WriteLine($"합계: {sum}, 곱셈: {product}");     }     static (int, int) Calculate(int a, int b)     {         return (a + b, a * b);     } } Tuple은 여러 값을 한 번에 반환할 때 사용되며 (.. 2025. 4. 12.
lock 키워드로 멀티스레딩 동기화 lock 키워드로 멀티스레딩 동기화 멀티스레드 환경에서는 하나의 리소스를  여러 스레드가 동시에 접근할 수 있기 때문에  데이터 무결성을 유지하려면 동기화가 필수입니다. C#의 lock 키워드를 사용하면 간단하게  **임계 구역(Critical Section)**을 만들어 스레드 충돌을 방지할 수 있습니다. using System; using System.Threading; class Counter {     private int _count = 0;     private readonly object _lock = new object();     public void Increment()     {         lock (_lock)         {             _count++;       .. 2025. 4. 11.
??= 널 병합 할당 연산자 ??= 널 병합 할당 연산자C# 8.0부터 도입된 ??= 연산자는 값이 null일 경우에만 할당을 수행합니다. 조건문 없이 깔끔하게 기본값을 설정할 수 있어 가독성과 생산성을  모두 향상시킬 수 있습니다. using System; class Program {     static void Main()     {         string name = null;         name ??= "기본 이름";         Console.WriteLine($"사용자 이름: {name}");     } } 출력 결과 사용자 이름: 기본 이름 ● ??=는 변수에 값이 null일 경우에만 오른쪽 값을 할당합니다. ● if (x == null) x = y;를 더 간결하게 표현한 것과 동일합니다. ● 코드 흐름을 깔끔.. 2025. 4. 10.
foreach와 yield return을 활용한 커스텀 이터레이터 foreach와 yield return을 활용한 커스텀 이터레이터 C#의 yield return을 사용하면 반복자의 상태를 직접 관리하지 않고도  커스텀 이터레이터를 간결하게 구현할 수 있습니다. 필터링, 지연 실행, 파이프라인 처리 등에 매우 유용합니다. using System; using System.Collections.Generic; class Program {     static void Main()     {         foreach (int prime in GetPrimesBelow(10))         {             Console.WriteLine($"소수: {prime}");         }     }     static IEnumerable GetPrimesBelow(.. 2025. 4. 8.
s 및 패턴 매칭으로 타입 검사 간소화하기 s 및 패턴 매칭으로 타입 검사 간소화하기C#의 is 키워드와 패턴 매칭을 활용하면  객체의 타입을 검사하고 동시에 캐스팅까지  깔끔하게 처리할 수 있습니다. as와 null 체크보다 안전하고, switch와 함께 사용하면  더 강력한 조건 분기를 만들 수 있습니다. using System; class Animal { } class Dog : Animal {     public void Bark() => Console.WriteLine("멍멍!"); } class Program {     static void Main()     {         Animal pet = new Dog();         if (pet is Dog dog)         {             dog.Bark();    .. 2025. 4. 7.
readonly 필드로 불변 객체 만들기 readonly 필드로 불변 객체 만들기  readonly 키워드는 객체 생성 이후 값을  변경할 수 없는 필드를 선언할 때 사용합니다. 이 키워드를 통해 클래스의 상태를 안정적으로 유지할 수 있으며,  특히 멀티스레딩 환경에서 유용합니다. using System; class Circle {     private readonly double _radius;     public Circle(double radius)     {         _radius = radius;     }     public double Area => Math.PI * _radius * _radius; } class Program {     static void Main()     {         Circle c = new C.. 2025. 4. 4.