C# 및 .NET의 핵심 개념 정리

값형과 참조형의 차이점

메모리 할당 방식, 스택/힙 저장 위치, 복사 전략 측면에서 비교한다. 주요 값형과 참조형 타입을 나열한다.

1. 메모리 구조와 저장 방식

  • 값형 (Value Type):
    • 데이터 자체를 직접 저장한다.
    • 일반적으로 스택에 할당되며, 클래스 멤버로 사용될 경우 해당 객체의 힙 영역에 포함된다.
    • 변수 대입 시 데이터 전체를 복사(깊은 복사)한다.
  • 참조형 (Reference Type):
    • 실제 데이터의 메모리 주소를 저장한다.
    • 인스턴스는 힙에 생성되며, 변수는 이 주소를 참조한다(스택에 주소 저장).
    • 대입 시 주소만 복사(얕은 복사)되므로 동일한 객체를 공유한다.

2. 대표적인 타입 예시

  • 값형: int, double, bool, DateTime(struct), enum
  • 참조형: class(예: string, object), 배열(int[]), interface, Delegate

3. 코드 예시 비교

int first = 42;                    // 값형 - 스택에 42 저장
int second = first;                // 복사 후 독립된 값 유지

object instance = new object();    // 참조형 - 힙에 인스턴스 생성
object copyRef = instance;         // 주소 복사 - 두 변수가 동일한 객체 참조

비동기 처리 기법

async/await의 목적과, 비동기 작업에서 발생할 수 있는 데드락 문제 해결 방법을 설명하며, Task.RunTask.Factory.StartNew의 활용 차이를 분석한다.

1. async/await의 역할

  • 비동기 로직을 동기식 코드처럼 작성 가능하게 해주는 패러다임.
  • 콜백 지옥 회피: 중첩된 콜백 없이 순차적 흐름 유지.
  • 비차단성: await 시 현재 스레드를 해제하고 다른 작업 수행 가능, 완료 후 복귀.
  • 컴파일러가 상태 머신으로 변환하여 일시정지 및 재개를 관리.

2. 데드락 방지 전략

  • 비동기 작업을 차단하지 않기:
    • 오류: .Result 또는 .Wait()를 동기 코드에서 사용하면 스레드 블록 발생.
    • 해결: 항상 await 사용, 차단 연산 금지.
  • 동기 컨텍스트 무시하기:
    • 라이브러리 내부에서는 ConfigureAwait(false)를 사용하여 원래 컨텍스트(예: UI 스레드)를 고려하지 않도록 한다.
    • 예시: var data = await FetchData().ConfigureAwait(false);
  • Task.Run vs Task.Factory.StartNew:
    • Task.Run:
      • 스레드 풀을 자동으로 사용.
      • 간단한 CPU 집약 작업에 적합.
      • 예: await Task.Run(() => HeavyCalculation(1000));
    • Task.Factory.StartNew:
      • 더 많은 제어 옵션 제공 (예: TaskCreationOptions.LongRunning).
      • 장시간 실행되는 작업이나 특수한 스케줄링이 필요한 경우 사용.
      • 예: var task = Task.Factory.StartNew(() => LongRunningProcess(), TaskCreationOptions.LongRunning);

델리게이트와 이벤트

델리게이트의 본질과 이벤트의 역할, 그리고 사용자 정의 이벤트의 구현 방법을 설명한다.

1. 델리게이트의 본질

  • 타입 안전한 함수 포인터로서, System.Delegate의 파생 클래스이다.
  • 메서드 서명을 정의하여 특정 형식의 메서드만 참조할 수 있도록 보장.
  • 다중 호출 지원: 하나의 델리게이트 인스턴스에 여러 메서드를 등록 가능 (+= 사용).

2. 이벤트와 델리게이트의 관계

  • 이벤트는 델리게이트의 래핑:
    • 이벤트는 특정 델리게이트 타입을 기반으로 하지만, 외부에서만 구독/취소 가능.
    • 내부에서만 Invoke 가능하므로 안전한 관찰자 패턴을 제공.
  • 예시 코드:
    public delegate void ClickHandler(object sender, EventArgs e);
    
    public class Button
    {
        public event ClickHandler? Clicked;
    
        public void TriggerClick()
        {
            Clicked?.Invoke(this, EventArgs.Empty);
        }
    }

3. 사용자 정의 이벤트 실습

public class EnvironmentalMonitor
{
    public delegate void TemperatureUpdateHandler(double temperature);
    public event TemperatureUpdateHandler? TemperatureUpdated;

    private double currentReading;
    
    public double CurrentTemperature
    {
        get => currentReading;
        set
        {
            currentReading = value;
            TemperatureUpdated?.Invoke(value);
        }
    }
}

비동기 프로그래밍 확장: 특성 사용

ASP.NET MVC의 [HttpGet], [Route] 등의 특성 기능을 설명하고, 사용자 정의 특성을 만드는 절차를 소개한다.

1. ASP.NET MVC 특성의 역할

  • [HttpGet]: 해당 액션 메서드가 오직 HTTP GET 요청만 처리하도록 제한.
  • 예시:
    [HttpGet]
    public ActionResult GetUser(int id)
    {
        return View();
    }
  • [Route]: URL 경로 템플릿을 정의하여 요청을 액션에 매핑.
  • 예시:
    [Route("api/products/{id}")]
    public ActionResult GetProductById(int id)
    {
        return Json(new { Id = id });
    }

2. 사용자 정의 특성 만들기

  • Attribute 상속:
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class AuditLogAttribute : Attribute
    {
        public string Message { get; }
    
        public AuditLogAttribute(string message)
        {
            Message = message;
        }
    }
  • 특성 적용:
    [AuditLog("사용자 정보 조회")]
    public ActionResult GetUserData(int userId)
    {
        return Json(...);
    }
  • 반사로 특성 읽기:
    var method = typeof(HomeController).GetMethod("GetUserData");
    var auditAttr = method.GetCustomAttribute<AuditLogAttribute>();
    Console.WriteLine(auditAttr?.Message); // 출력: "사용자 정보 조회"

태그: C# .NET async-await Task Delegate

6월 18일 21:35에 게시됨