플래그를 사용한 복합 열거형 구성
특성 [Flags]를 적용하면 열거형 값이 비트 단위로 조합 가능해집니다. 이는 권한 또는 상태를 다중 조합으로 표현할 때 유용합니다.
[Flags]
public enum Permissions
{
Read = 1,
Write = 2,
Execute = 4,
Admin = Read | Write | Execute
}
다음과 같이 여러 값을 결합하여 사용할 수 있습니다:
var userPermissions = Permissions.Write | Permissions.Read;
Console.WriteLine(userPermissions); // 출력: Read, Write
if (userPermissions.HasFlag(Permissions.Read))
{
Console.WriteLine("읽기 권한 있음");
}
객체 해체 (Deconstruct) 기능 활용
Deconstruct 메서드를 통해 객체에서 특정 필드를 직접 추출할 수 있습니다. 이는 구조 분해 할당과 함께 사용됩니다.
public class Order
{
public DateTime CreatedAt { get; set; }
public string Code { get; set; }
public void Deconstruct(out DateTime createdAt, out string code)
{
createdAt = CreatedAt;
code = Code;
}
}
// 사용 예시
var order = new Order(DateTime.Now, "ORD-001");
(var date, var id) = order;
Console.WriteLine($"생성일: {date:yyyy-MM-dd}, 주문번호: {id}");
암시적 및 명시적 변환 연산자
사용자 정의 타입 간의 자동 변환을 정의할 수 있습니다.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student
{
public string FullName { get; set; }
public static implicit operator Student(Person person)
{
return new Student { FullName = $"{person.FirstName} {person.LastName}" };
}
public static explicit operator Person(Student student)
{
return new Person { FirstName = student.FullName };
}
}
// 사용
var person = new Person { FirstName = "홍", LastName = "길동" };
Student student = person; // 암시적 변환
Person person2 = (Person)student; // 명시적 변환
반복 가능한 컬렉션 처리: IEnumerable과 yield 반환
IEnumerable 인터페이스는 반복 가능한 컬렉션을 정의하며, yield return은 지연 평가를 지원합니다.
public IEnumerable<string> GetEmployeeNames()
{
yield return "김철수";
yield return "박영희";
yield break; // 조건에 따라 종료
}
// 사용
var names = GetEmployeeNames().ToList();
Console.WriteLine(string.Join(", ", names));
DateTime, DateTimeOffset, TimeSpan 차이점
- DateTime: 로컬 시간대 기준, 시간 정보 포함.
- DateTimeOffset: UTC와의 오프셋을 명시적으로 저장, 국제화 시 유용.
- TimeSpan: 시간 간격을 표현, 두 시점 사이의 차이 계산.
이벤트 처리 방식 비교
기본적인 델리게이트 기반 이벤트와 이벤트 매개변수를 사용하는 고급 방식을 비교합니다.
// 기본 이벤트 선언
public delegate bool OrderEventHandler(string orderCode);
public event OrderEventHandler OrderCreated;
// 이벤트 매개변수 사용
public class PaymentSucceededArgs : EventArgs
{
public string OrderId { get; set; }
public PaymentSucceededArgs(string orderId) => OrderId = orderId;
}
public event EventHandler<PaymentSucceededArgs> PaymentCompleted;
익명 타입 활용
임시 데이터 구조를 빠르게 생성할 수 있습니다.
var address = new { Street = "제주로 123", City = "서귀포" };
Console.WriteLine(address.Street); // 제주로 123
LINQ의 into 키워드 및 그룹화 후 전개
into는 join 후 그룹화된 결과를 임시 변수로 저장하고, 이후 from 문에서 전개할 수 있게 합니다.
var query = from customer in customers
join purchase in purchases.Where(p => p.Price > 5000)
on customer.Id equals purchase.CustomerId
into customerPurchases
from cp in customerPurchases.DefaultIfEmpty()
select new
{
Name = customer.Name,
Price = cp?.Price,
Product = cp?.Name
};
멀티스레딩에서 volatile 키워드의 역할
volatile는 공유 변수의 값이 캐시되지 않도록 보장하며, 모든 스레드가 메모리에서 직접 읽고 쓰도록 합니다. 단, 원자성 연산이나 잠금 없이도 동작하지 않습니다.
private volatile bool _isRunning = true;
// 스레드에서 읽기
while (_isRunning)
{
// 작업 수행
}
프로그램 세부 정보 설정: AssemblyDescriptionAttribute
어셈블리에 설명을 추가할 수 있습니다.
[assembly: AssemblyDescription("이 어셈블리는 사용자 관리 시스템입니다.")]
MemoryCache 설정 및 최적화
ASP.NET Core에서 IMemoryCache를 설정할 때 다양한 옵션을 조정할 수 있습니다.
services.AddMemoryCache(options =>
{
options.SizeLimit = 100; // 최대 항목 수 (상대적)
options.CompactionPercentage = 0.1; // 초과 시 압축 비율
options.ExpirationScanFrequency = TimeSpan.FromSeconds(3); // 스캔 주기
});
공유 리소스 제어: SemaphoreSlim
비동기 환경에서 동시 접근을 제어하기 위한 경량 락입니다.
static readonly SemaphoreSlim _semaphore = new(1);
await _semaphore.WaitAsync();
try
{
// 공유 리소스 접근
}
finally
{
_semaphore.Release();
}
반사 기술: MakeGenericType 활용
런타임에 제네릭 타입을 동적으로 생성할 수 있습니다.
Type genericInterface = typeof(IAnmail<>).MakeGenericType(typeof(string));
object instance = Activator.CreateInstance(typeof(Lion));
var method = genericInterface.GetMethod("GetName");
var result = method.Invoke(instance, null);
Console.WriteLine(result); // "사자"