Deff_Dev
[C#] C# 심화 문법 (Generic, Linq, Reflection) 본문
제네릭이란 무엇인가요?
- 제네릭(Generic)은 데이터 형식을 일반화하여 코드의 유연성을 높이는 기능
- 일반화 ⇒ 특수한 개념으로부터 공통된 개념을 찾아 묶는 것 → 데이터 형식
- 제네릭을 사용하면 데이터 형식에 의존하지 않는 클래스를 작성할 수 있어, 코드 재사용성과 타입 안정성을 높일 수 있다.
[Unity/C#] 일반화 프로그래밍 (Generic)
일반화란 ?- 특수한 개념으로부터 공통된 개념을 찾아 묶는 것 이러한 일반화를 이용하는 프로그래밍이 일반화 프로그래밍 ! 일반화 프로그래밍의 일반화 대상 ▶ 데이터 형식 (Data Type)일반화
deff-dev.tistory.com
람다식(Lambda Expression)이 무엇인지 설명해주세요.
(input-parameters) => expression // 식 람다
(input-parameters) => { <sequence-of-statements> } // 문 람다
Func<int, int> square = x => x * x; // 식 람다
Action<string> greet = name => { Console.WriteLine("Hello, " + name); }; // 문 람다
- 익명 메소드를 만들기 위해 람다 선언 연산자 (⇒)를 사용하는 식으로, 식이 본문으로 포함된 식 람다, 문 블록이 본문으로 포함된 문 람다가 있다.
LINQ란 무엇인가요?
int[] numbers = { 1, 2, 3, 4, 5 };
// 쿼리문 형태
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
// 람다식 형태
var evenNumbersLambda = numbers.Where(num => num % 2 == 0);
- c# 언어에서 쿼리 기능을 사용하는 것으로 데이터를 빠르고 편리하게 추출 및 처리할 수 있다.
- Linq == (SQL + 람다식)
- Linq는 데이터 그룹화가 강점이다.
리플렉션(Reflection)이 뭔지, 사용을 해봤다면 어떤 이유에서 사용했는지 설명해주세요.
- 정의
- 리플렉션은 프로그램 실행 중 메소드, 프로퍼티 등 인스턴스의 데이터 타입 정보를 확인하거나 검사하려는 경우 사용되는 기능으로 컴파일 시 알 수 없었던 타입이나 멤버들을 찾아내고 사용할 수 있게 해준다.
- 사용
using System;
using System.Reflection;
public class Person
{
public string Name { get; set; }
private int age;
public Person(string name, int age)
{
Name = name;
this.age = age;
}
private void DisplayAge()
{
Console.WriteLine($"Age: {age}");
}
}
public class ReflectionExample
{
public static void Main(string[] args)
{
// 타입 정보 가져오기
Type personType = typeof(Person);
// 생성자 호출
object personInstance = Activator.CreateInstance(personType, "John", 30);
// 필드 및 속성 정보 가져오기
PropertyInfo nameProperty = personType.GetProperty("Name");
FieldInfo ageField = personType.GetField("age", BindingFlags.NonPublic | BindingFlags.Instance);
// 값 설정 및 가져오기
nameProperty.SetValue(personInstance, "Jane");
Console.WriteLine(nameProperty.GetValue(personInstance)); // Output: Jane
// 비공개 메서드 호출
MethodInfo displayAgeMethod = personType.GetMethod("DisplayAge", BindingFlags.NonPublic | BindingFlags.Instance);
displayAgeMethod.Invoke(personInstance, null); // Output: Age: 30
}
}
- 데이터 타입의 정보(예: 필드, 속성, 메서드)를 확인하거나, 동적으로 객체의 멤버/필드에 접근하고 수정할 수 있다.
- 리플렉션의 단점에 대해 설명해주세요.
- 성능 오버헤드
- 리플렉션은 런타임에 타입 정보를 조회하고 조작하기 때문에 성능에 부담이 될 수 있습니다.
- 타입 안전성 저하
- 컴파일 시에 타입 체크가 이루어지지 않기 때문에 런타임 오류가 발생할 수 있습니다.
- 복잡성 증가
- 리플렉션을 사용하는 코드는 일반적으로 더 복잡하고 유지보수가 어려울 수 있습니다.
- 성능 오버헤드
using System;
using System.Collections.Generic;
public class Box<T>
{
public T Value { get; set; }
public void DisplayValue()
{
Console.WriteLine($"Value: {Value}");
}
}
class Program
{
static void Main(string[] args)
{
Box<int> intBox = new Box<int> { Value = 123 };
Box<string> strBox = new Box<string> { Value = "Hello, World" };
Box<DateTime> dateBox = new Box<DateTime> { Value = DateTime.Now };
intBox.DisplayValue();
strBox.DisplayValue();
dateBox.DisplayValue();
}
}
- 다음 코드에서 제네릭을 사용한 부분을 식별하고, 해당 코드가 제네릭을 사용하지 않았을 때 발생할 수 있는 문제점에 대해 설명하세요.
- Box 클래스가 제네릭을 사용한 제네릭 클래스이다.
- 제네릭을 사용하지 않는다면 value의 데이터 타입이 변할 때마다 데이터 타입만 다른 중복 클래스를 만들어줘야한다.
- 아래 코드가 어떤 기능을 하는지, 어떤 방식으로 동작하는지 간단하게 설명해주세요.
public static T Max<T>(T a, T b) where T : IComparable<T> { return a.CompareTo(b) > 0 ? a : b; }
- IComparable를 상속받는 데이터 타입의 입력 값 둘 중 큰 변수를 반환하는 정적 일반화 함수이다.
- 제네릭을 사용하여 어떤 데이터 타입이든 대응가능하게 작성하여 코드 재사용성과 타입 안정성을 높일 수 있다.
'면접 질문 정리 > C#' 카테고리의 다른 글
[C#] 가비지 컬렉터 (Garbage Collectior) (0) | 2024.07.08 |
---|---|
[C#] 상속과 인터페이스 (0) | 2024.07.05 |
[C#] 스택 메모리, 힙 메모리 (0) | 2024.07.04 |
[C#] 콜백, delegate, event (0) | 2024.07.03 |
[C#] 객체 지향 프로그래밍 (0) | 2024.07.02 |