본문 바로가기
Study/개념 정리

[Study] 제네릭 & 람다 & LINQ & Reflection

by chobbo 2024. 7. 9.

제네릭이란?

- 클래스나 메서드에서 사용할 내부 데이터 타입을 일반화한 것

- 제네릭을 사용하면 박싱, 언박싱이 수행되지 않아 성능에 좋다.

   (Object 타입을 사용하면 박싱& 언박싱이 일어남)

- 컴파일시 데이터 형식이 결정 되는 것이 아니라 코드에서 메서드를 호출할 때 데이터 형식이 정해진다

- 클래스나 인터페이스, 메서드를 사용할 때 동일한 기능을 수행하지만 입력하는 데이터 형식만 틀린 경우 사용

void Swap(int x, int y)
{
    int temp = y;
    y = x;
    x = temp;
}

void Swap(float x, float y)
{
    float temp = y;
    y = x;
    x = temp;
}

// 제네릭 사용
void Swap<T>(T x, T y)
{
    T temp = y;
    y = x;
    x = temp;
}

 

- 제약조건을 걸어놓을 수도 있다.

public class Swap<T> where T : 제약조건 {}

 

 

람다식이란?

 

- 접근자, 함수 이름이 없는 익명 함수(재사용 X)

- 람다 연산자 (=>)를 사용한다

// 입력 파라미터 => 실행문장 => 식람다
x => x+1

 

- 람다식을 사용하면 코드가 간결해진다

- 식람다 x => x+1

  문람다 x => {Console.WriteLine();}

- 보통 return이 안되지만 Func, Delegate를 사용하면 return이 가능하다 

- 람다는 데이터를 읽는 것 밖에 안된다 => Setter가 없다. Getter만 있다.

 

 

 

 

LINQ란?

- Language Integrated Query의 약자

- C#에서 Query 기능을 사용할 수 있는 기술

- SQL + Lambda

- 람다식을 사용해 작성 가능하며, Query 기능을 통해 내가 원하는 데이터만 가져올 수 있다.

string[] arr = { "Apple", "Banana", "Car", "Angular", "Add", "Sum" };

var answer = from str in arr
             where str.Length > 3
             select str;
           
// answer = Apple, Banana, Angular
// 쿼리문 형태
var evenNumbers = from num in numbers
                  where num % 2 == 0
                  select num;

// 람다식 형태
var evenNumbersLambda = numbers.Where(num => num % 2 == 0);
더보기

from : 어떤 데이터에서 찾을 것인지
where : 원하는 값을 추출하기 위한 조건
select : 데이터에서 어떤 항목을 추출할 것인지

 

- 장점 : 반복문과 조건문을 줄일 수 있다.

- 단점 

    1. for, foreach와 같은 반복문을 사용하는 것보다 성능이 저하될 수 있다.

    2. for > foreach > Linq순으로 성능이 좋은데, .Net7부터는 Linq의 속도가 굉장히 빨라졌다.

       하지만 유니티에서는 .Net7을 지원하지 않으므로 Linq 사용을 지양하는 것이 좋다. 확인해야됨

 

   

 

 

 

 

 

Reflection이란?

- 프로그램 실행 도중에 코드를 검사만 해주는 기능

- 프로그램 실행 중 어셈블리의 내용을 확인하거나, 검사하려는 경우 사용되는 기능이다.

- 리플렉션은 프로그램 실행 중 메소드, 프로퍼티 등 인스턴스의 데이터 타입 정보를 확인하거나 검사하려는 경우 사용되는 기능으로, 컴파일 시 알 수 없었던 타입이나 멤버들을 찾아내고 사용할 수 있게 해준다.

형식 메서드  설명
Type GetType() 지정된 형식의 Type 개체를 가져옵니다. 
MemberInfo[] GetMembers()  해당 형식의 멤버 목록을 가져옵니다.
MethodInfo[] GetMethods()  해당 형식의 메소드 목록을 가져옵니다.
FieldInfo[] GetFields()  해당 형식의 필드 목록을 가져옵니다.

 

- GetType()은 System 라이브러리에서 제공해준다. 리플렉션이 아님. 이걸 리플렉션으로 쓰려면 Type에 할당해서 써야된다.

 

//클래스의 이름을 출력하는 코드
public class Character
{
    public int Level { get; set; }
    public void PrintClassName()
    {
    	Type type = this.GetType(); // 이렇게 Type에 할당 하는 것이 Reflection
        Console.WriteLine("Class Name: " + type.Name);
        
    }
}
// 특정 클래스의 메서드 목록
Type type = typeof(클래스 이름);
MethodInfo[] methods = type.GetMethods(BindingFlags.Public| BindingFlags.Instance | BindingFlags.DeclaredOnly);



- 리플렉션의 단점

1. 컴파일 시에 타입 안정성을 해친다

2. 속도가 느리다

3. 성능에 좋지 않다

 

=> 리플렉션을 사용하기 보다는 인터페이스 등을 상속하여 타입을 구성하도록 하는 것이 좋다.

 

 

예시

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();
    }
}

 

1. 다음 코드에서 제네릭을 사용한 부분을 식별하고, 해당 코드가 제네릭을 사용하지 않았을 때 발생할 수 있는 문제점에 대해 설명하세요.

 

- 코드에서 Box 클래스를 int, string, DateTime 데이터 형식으로 사용하고 있다.

만약 제네릭을 사용하지 않는다면 Box 클래스를 데이터 형식 별로 여러개 선언해주어야 한다.

이렇게 되면 코드 재사용성이 떨어지므로 좋은 코드가 아니다.

 


2. 아래 코드가 어떤 기능을 하는지, 어떤 방식으로 동작하는지 간단하게 설명해주세요.

public static T Max<T>(T a, T b) where T : IComparable<T> { return a.CompareTo(b) > 0 ? a : b; }

 

a,b의 매개변수를 받아 더 큰 값을 반환한다.

더보기

a.CompareTo(b) 

- a가 더 크면 1, 더 작으면 -1을 반환한다.

- 위 코드에서 a.CompareTo(b)  의 값이 0보다 크면 a, 0보다 작으면 b를 return 한다

해당 제네릭 클래스는 IComparable이라는 인터페이스 구현 제약 조건(데이터 타입을 강제)을 가진다. 

IComparable(기본적으로 상속받고 있는 인터페이스이다!)을 상속받는 데이터 타입이어야 한다.

 

 

** IEnumerable **

=> 기본 제공되는 인터페이스 

=> 리스트나 Collection 자료형의 함수들을 제공

=> 얘를 상속받아야 foreach문도 사용 가능

=> IEnumerator 이랑은 다르다 -> 코루틴은 반환값이 없음, IEnumerable은 반환값 존재

'Study > 개념 정리' 카테고리의 다른 글

[Study] Stack  (0) 2024.07.11
[Study] LinkedList  (0) 2024.07.10
[Study] GC  (0) 2024.07.08
[Study] 상속과 인터페이스  (0) 2024.07.05
[Study] 스택 메모리 , 힙 메모리  (0) 2024.07.03