본문 바로가기
반응형

C#66

“C# readonly: 생성 후 불변을 보장해 버그를 줄이고 성능을 챙기는 설계 키워드” 좋은 질문이에요! C#의 readonly는 “한 번 정해진 값(또는 상태)을 바꾸지 않겠다”는 불변(immutability) 의도를 코드에 담아 주는 키워드예요. 쓰임새가 몇 가지(필드, 구조체, 멤버 등)로 나뉘어 헷갈리기 쉬우니 교재식으로 차근히 정리해 드릴게요. (가정: C# 12 / .NET 8)1) 왜 생겼는가 — “변하면 안 되는 건, 애초에 못 바꾸게”버그 예방: 실수로 값을 바꾸는 것을 컴파일 단계에서 차단합니다.가독성/의도 전달: “생성 후 불변”이라는 설계를 명확히 보여줍니다.최적화/성능: JIT가 읽기 전용임을 가정해 불필요한 방어적 복사(defensive copy)를 줄이거나 인라이닝에 유리합니다(특히 readonly struct, readonly members).2) 무엇인가 — .. 2025. 10. 10.
“IDisposable: 가비지 컬렉터가 다 못하는 ‘자원 반납’을 결정적으로 보장하는 계약” 좋은 질문이에요! IDisposable을 구현(“상속”)하는 이유는 **“수명(lifetime)이 끝난 자원을 즉시·명시적으로 해제하기 위해서”**입니다. 가비지 컬렉터는 메모리만 자동으로 돌려주지만, 파일 핸들/소켓/데이터베이스 연결/윈도우 핸들 같은 비관리 자원은 누수가 생길 수 있거든요. 아래 구조로 정리해 볼게요. (가정: C# 12 / .NET 8)1) 왜 생겼는가 — “가비지 컬렉터만으로는 부족하다”GC 한계: .NET GC는 관리 힙 메모리만 회수합니다. OS 자원(파일, 소켓 등)은 GC 타이밍과 무관하게 즉시 닫아야 안전합니다.결정적 해제(Deterministic cleanup): IDisposable.Dispose()를 호출하면 그 즉시 자원을 반환할 수 있습니다. using/await.. 2025. 10. 10.
C# “??는 ‘null이면 우변’ — 안전한 기본값 지정의 한 줄 공식” 좋은 질문이에요! 말씀하신 생성자에서의 ??는 **null 병합 연산자(null-coalescing operator)**입니다. 코드 조각을 기준으로 교재식으로 정리해 드릴게요.1) 왜 생겼는가 — “null이면 대체값을 쓰자”메서드 인자나 계산 결과가 null일 수도 있는 상황에서, 매번 if (x == null) ...를 쓰면 코드가 장황해집니다. 그래서 *“좌변이 null이면 우변을 대신 쓰자”*라는 패턴을 한 줄로 쓰기 위해 ??가 생겼습니다.2) 무엇인가 — left ?? right의 의미정의: left가 null이 아니면 left를, null이면 right를 반환합니다.평가 순서/성능: left를 먼저 평가하고, left가 null이 아닐 때는 right는 평가하지 않습니다(지연 평가).→ D.. 2025. 10. 10.
“C# 값 형식에도 없음(null)을 — T? = Nullable<T> 제대로 쓰는 법” 1) 왜 생겼는가 — “값 형식도 값이 없을 수 있다”문제 배경: 기본값(Value type)은 원래 null을 가질 수 없어요. 예를 들어 int는 0, 1, -5 같은 “숫자”만 가능하고 “값 없음”을 표현할 방법이 없었습니다.필요성: DB의 NULL, 폼 입력의 미입력, 센서값 미수집 같은 “없음” 상태를 정확히 모델링해야 할 때가 많습니다.해결: T?(여기서 T는 값 형식) 를 도입해 null을 담을 수 있게 했습니다. 즉, int?, bool?, DateTime? 처럼 “값이거나(null이 아닐 때) 없다(null일 때)”를 표현합니다.2) 무엇인가 — T?는 사실 Nullable의 문법 설탕정의: T?는 값 형식 T에 대해 Nullable로 컴파일됩니다.구성: Nullable는HasValue .. 2025. 10. 10.
error. 이벤트핸들러 이름 충돌 문제 원인은 이름 충돌이에요.당신이 만든 VIK.ImageGrabbedEventArgs (버퍼+카메라)와Basler SDK의 Basler.Pylon.ImageGrabbedEventArgs (GrabResult 포함)이 같은 이름이라, StreamGrabber.ImageGrabbed 구독 시 컴파일러가 잘못된 쪽을 참고하고 있어요. 그래서“EventHandler에 맞는 오버로드 없음”“DisposeGrabResultIfClone, GrabResult가 없음”같은 에러가 터집니다. (이 멤버들은 Basler 쪽에만 있어요.)빠른 해결: 형식 별칭 + 핸들러 이름 구분Basler 파일에서 형식 별칭을 추가하고, 이벤트 핸들러를 Basler 전용으로 분리하세요.1) using 별칭 추가 (파일 상단)using .. 2025. 9. 22.
volatile는 멀티스레드에서 “가벼운 동기화”를 위한 읽기/쓰기 가시성 보장 장치 volatile는 멀티스레드에서 “가벼운 동기화”를 위한 읽기/쓰기 가시성 보장 장치라고 이해하면 편합니다.private volatile bool _isGrabbing = false;처럼 플래그에 쓰면, 다른 스레드가 값 변경을 즉시 보고 잘 멈추거나 시작할 수 있게 해줘요.volatile가 뭔가요?효과: 해당 필드에 대한 **읽기(Read)**와 **쓰기(Write)**가**CPU/컴파일러 재정렬(reordering)**로 서로 엇갈리지 않게 만들고,코어별 캐시/레지스터에만 머물다 안 보이는(stale) 값이 되는 일을 막아,다른 스레드에서 최신 값을 즉시 관측할 수 있게 합니다.(쉽게 말해: “바로 보이게 하고, 읽기/쓰기 순서를 뒤바꾸지 말라”는 메모리 장벽을 넣어줍니다. 읽기는 acquire, 쓰.. 2025. 9. 19.
왜 IDisposable을 구현하나요? 핵심 한 줄 요약**IDisposable = “내가 잡고 있는 외부 자원(파일 핸들, GDI, 스레드/Task/Timer 등)을 사용이 끝나면 즉시, 확정적으로 해제할 수 있게 해주는 계약(패턴)”**입니다.GC는 메모리만 회수하지 OS 자원(파일·소켓·GDI·스레드 핸들 등)은 즉시 정리하지 못하므로, 이런 자원을 가진 타입은 반드시 IDisposable을 구현해야 해요.왜 IDisposable을 구현하나요?결정적(Deterministic) 해제using (...) { ... } 블록이 끝나는 즉시 Dispose()가 호출되어 OS 핸들/타이머/스레드/그래픽 자원 등을 반납합니다.GC는 언제 실행될지 몰라요(비결정적). 파일 잠금·GDI 핸들 같은 건 지연 해제되면 곧바로 문제가 납니다.리소스 누수/잠.. 2025. 9. 19.
“직접 델리게이트 콜백” → “.NET 표준 이벤트 패턴(Event + EventArgs)” 왜 바꿨나? (Delegate → Event + EventArgs)1) .NET 표준 이벤트 패턴에 맞춤.NET에서 이벤트는 관례적으로 event EventHandler 형태를 써요.이렇게 하면 구독/해제(+=, -=), 멀티캐스트(여러 핸들러 동시 호출), 외부에서 임의 호출 차단 같은 이벤트 전용 보호 장치가 자동으로 따라옵니다.반면, public OnImageGrabbedEventDelegate OnImageGrabbedCallback; 같은 일반 필드 델리게이트는외부에서 통째로 갈아끼우기가 가능(기존 구독이 날아갈 위험)외부 코드가 임의로 호출도 가능(캡슐화 약함)멀티 구독/해제 동작이 명확하지 않음2) 시그니처 표준화: object sender, TEventArgs e이벤트 핸들러는 통일된 모양.. 2025. 9. 19.
sealed를 왜 써야 할까? sealed는 **“상속 불가”**를 뜻해요.즉 public sealed class ImageGrabbedEventArgs : EventArgs 라면, 이 클래스를 다른 클래스가 상속(derive)할 수 없습니다.왜 쓰나요?설계 의도 고정: 이벤트 페이로드 형태를 바꾸지 않도록 방지(파생형으로 변형 금지).안전성: 파생 클래스가 동작을 바꾸어 역호환/버그를 유발하는 것을 차단.성능 이점: JIT가 가상 호출을 줄이고(inlining 등) 최적화할 여지가 생김.간단한 데이터 전달용(EventArgs 계열)은 보통 불변 + sealed로 두는 게 흔한 패턴.특징 요약sealed class → 상속 금지 (하지만 인터페이스 구현은 가능).sealed는 클래스에 붙이면 상속을 막고, 메서드에 붙이면 overri.. 2025. 9. 19.
C#의 readonly 키워드 1) readonly가 뭔가요?필드(멤버 변수)에 붙이는 한정자로,선언 시 또는 생성자(ctor) 안에서만 한 번 값을 할당할 수 있고, 그 이후에는 수정이 불가능합니다.즉, 객체가 만들어진 뒤에는 바뀌지 않아야 할 값에 사용합니다.(정확히 말하면 참조형의 경우 **참조(주소)**가 고정될 뿐, 참조 대상 내부 상태까지 자동으로 불변이 되는 것은 아닙니다.)2) 왜/언제 쓰나요? (써야 할 이유)불변성(immutability) 보장: 실수로 값이 바뀌는 버그를 차단합니다. 클래스 불변식을 지키기 쉬워요.코드 의도 표현: “이 값은 생성 시 결정되고 이후 변하지 않는다”를 컴파일러 수준에서 명시합니다.스레드 안정성에 기여: 공유되는 상태가 줄어들어 동시성 버그 위험을 줄입니다.설계 간결화: 의존성, 구성(.. 2025. 9. 19.
반응형