SeokguKim's Garage

A little space for SeokguKim


C# 내용 정리

Tags: development, csharp

알고 있는 중요한 내용 정리

아무래도 여유가 있는 시간에 C# 프로그래밍 언어와 Lua에 대한 기본적인 이해를 정리하는 것이 좋을 것 같습니다. 그래서 알고 있는 C#에 대한 내용을 먼저 정리해보고자 합니다.

C#

C#은 마이크로소프트에서 개발한 객체 지향 프로그래밍 언어로, .NET 프레임워크와 함께 사용됩니다. C#은 Java와 유사한 문법을 가지고 있으며, 강력한 타입 시스템과 메모리 관리 기능을 제공합니다. 주요 특징으로는 다음과 같습니다:

interface와 추상 클래스

C#에서 interface와 추상 클래스는 객체 지향 프로그래밍에서 중요한 개념입니다. 이 둘은 공통된 기능을 정의하는 데 사용되지만, 몇 가지 차이점이 있습니다.

public interface IAnimal
{
    void Speak();
}
public abstract class Animal
{
    public abstract void Speak();
    public void Sleep()
    {
        Console.WriteLine("Sleeping...");
    }
}

더 읽어보기: https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/interfaces

IEnumerable, List, Collection

C#에서 IEnumerable<T>, List<T>, Collection<T>는 컬렉션을 다루는 데 사용되는 중요한 인터페이스와 클래스입니다. 이들은 데이터 구조를 정의하고 데이터를 저장하고 조작하는 데 사용됩니다.

public class MyCollection : IEnumerable<int>
{
    private List<int> _items = new List<int>();

    public IEnumerator<int> GetEnumerator()
    {
        return _items.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (var number in numbers)
{
    Console.WriteLine(number);
}
public class MyCollection : Collection<int>
{
    protected override void InsertItem(int index, int item)
    {
        base.InsertItem(index, item);
        Console.WriteLine($"Item {item} added at index {index}");
    }

    protected override void RemoveItem(int index)
    {
        Console.WriteLine($"Item {this[index]} removed from index {index}");
        base.RemoveItem(index);
    }
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/tour-of-csharp/tutorials/list-collection

IEnumerator

IEnumerator는 C#에서 컬렉션을 순회하는 데 사용되는 인터페이스입니다. 이 인터페이스는 컬렉션의 요소를 반복할 수 있는 기능을 제공합니다. IEnumerator는 MoveNext(), Reset(), Current 속성을 포함하여 컬렉션의 현재 위치를 추적하고 요소에 접근할 수 있게 합니다.

public class MyEnumerator : IEnumerator<int>
{
    private int[] _items;
    private int _position = -1;

    public MyEnumerator(int[] items)
    {
        _items = items;
    }

    public bool MoveNext()
    {
        _position++;
        return (_position < _items.Length);
    }

    public void Reset()
    {
        _position = -1;
    }

    public int Current => _items[_position];

    object IEnumerator.Current => Current;

    public void Dispose() { }
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/api/system.collections.generic.ienumerator-1?view=net-9.0

이벤트와 델리게이트

C#에서 이벤트와 델리게이트는 객체 간의 통신을 위한 중요한 메커니즘입니다. 이 둘은 밀접하게 연결되어 있으며, 이벤트 기반 프로그래밍을 지원합니다.

public delegate void Notify(string message);

public class Notifier
{
    public event Notify OnNotify;

    public void Notify(string message)
    {
        OnNotify?.Invoke(message);
    }
}
public class Button
{
    public event EventHandler Click;

    public void OnClick()
    {
        Click?.Invoke(this, EventArgs.Empty);
    }
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/events-overview

메모리 관리

C#의 가비지 컬렉션은 자동 메모리 관리 기능으로, 사용하지 않는 객체를 자동으로 식별하고 메모리를 해제합니다. 이는 개발자가 메모리 누수나 해제되지 않은 객체로 인한 문제를 걱정하지 않아도 되게 합니다. 가비지 컬렉션은 다음과 같은 방식으로 작동합니다:

  1. 세대별 가비지 컬렉션(Genertion-Based): C#은 객체를 세대별로 관리합니다. 새로 생성된 객체는 0세대에 속하고, 사용되지 않으면 1세대로 이동하며, 다시 사용되지 않으면 2세대로 이동합니다. 오래된 객체일수록 가비지 컬렉션이 덜 자주 발생합니다.
  2. 마크 앤 스윕(Mark-and-Sweep): 가비지 컬렉션은 "마크 앤 스윕" 알고리즘을 사용합니다. 먼저, 사용 중인 객체를 마크하고, 이후 마크되지 않은 객체를 메모리에서 해제합니다.
  3. 압축(Compaction): 가비지 컬렉션 후에는 메모리 단편화를 방지하기 위해 객체를 압축할 수 있습니다. 이는 메모리 사용 효율을 높이는 데 도움이 됩니다.

IDisposable과 using

C#에서 IDisposable 인터페이스는 리소스 해제를 위한 메서드를 정의합니다. 이 인터페이스를 구현하면 객체가 더 이상 필요하지 않을 때 리소스를 명시적으로 해제할 수 있습니다. using 문을 사용하면 자동으로 Dispose() 메서드를 호출하여 리소스를 해제할 수 있습니다.

public class Resource : IDisposable
{
    public void Dispose()
    {
        // 리소스 해제 로직
    }
}
using (Resource resource = new Resource())
{
    // 리소스를 사용하는 코드
} // using 블록을 벗어나면 Dispose()가 자동으로 호출됩니다.

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/api/system.idisposable?view=net-9.0

LINQ

LINQ(Language Integrated Query)는 C#에서 데이터 쿼리를 간결하게 작성할 수 있는 기능입니다. LINQ를 사용하면 컬렉션, 데이터베이스, XML 등 다양한 데이터 소스에 대해 일관된 방식으로 쿼리를 작성할 수 있습니다. 주요 특징은 다음과 같습니다:

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/tutorials/working-with-linq

비동기 프로그래밍

C#의 비동기 프로그래밍은 async와 await 키워드를 사용하여 구현됩니다. 이를 통해 I/O 작업이나 네트워크 요청과 같은 시간이 오래 걸리는 작업을 비동기적으로 처리할 수 있습니다. 이는 JavaScript와도 비슷하며, 주요 특징은 다음과 같습니다:

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/asynchronous-programming/async-scenarios

제네릭 (Generics)

C#의 제네릭은 클래스, 인터페이스, 메서드 등을 특정 타입에 국한되지 않고 일반화된 방식으로 정의할 수 있게 해줍니다. 이를 통해 코드 재사용성을 높이고 타입 안정성을 보장할 수 있습니다. 주요 특징은 다음과 같습니다:

public class GenericRepository<T> where T : class
{
    protected readonly List<T> _items = new List<T>();

    public void Add(T item)
    {
        _items.Add(item);
    }

    public T GetById(int id)
    {
        return _items.FirstOrDefault();
    }
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/types/generics

예외 처리 (Exception Handling)

C#에서 예외 처리는 프로그램 실행 중 발생할 수 있는 오류나 예외적인 상황을 관리하는 메커니즘입니다. try-catch-finally 블록을 사용하여 예외를 처리합니다.

public class FileManager
{
    public static string ReadFile(string filePath)
    {
        try
        {
            string content = System.IO.File.ReadAllText(filePath);
            return content;
        }
        catch (System.IO.FileNotFoundException ex)
        {
            Console.WriteLine($"파일을 찾을 수 없습니다: {ex.FileName}");
            throw;
        }
        catch (System.Exception ex)
        {
            Console.WriteLine($"오류 발생: {ex.Message}");
            return string.Empty;
        }
        finally
        {
            Console.WriteLine("파일 읽기 시도 완료.");
        }
    }
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/exceptions/exception-handling

속성 (Properties)

속성은 필드처럼 보이지만 접근자(getter)와 설정자(setter) 메서드를 통해 값을 읽거나 쓰는 클래스 멤버입니다. 캡슐화를 유지하면서 데이터에 유연하게 접근할 수 있도록 합니다.

public class Person
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentException("이름은 null이거나 공백일 수 없습니다.");
            }
            _name = value;
        }
    }
    public int Age { get; set; }
    public string Details => $"{Name} (Age: {Age})";
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/programming-guide/classes-and-structs/properties

람다 식 (Lambda Expressions)

람다 식은 익명 함수를 간결하게 표현하는 방법입니다. 주로 LINQ 쿼리나 델리게이트를 사용하는 곳에서 코드를 짧고 가독성 있게 만드는 데 사용됩니다.

public class LambdaExample
{
    public void Demonstrate()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

        List<int> evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
        // evenNumbers: [2, 4, 6]

        List<int> squaredNumbers = numbers.Select(n => n * n).ToList();
        // squaredNumbers: [1, 4, 9, 16, 25, 36]

        Action<string> printMessage = message => Console.WriteLine(message);
        printMessage("Hello Lambda!");

        Func<int, int, int> add = (a, b) => a + b;
        int sum = add(5, 3); // sum: 8
    }
}

더 읽어보기: https://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/operators/lambda-expressions

Unity와 C#

Unity는 C#을 주요 스크립트 언어로 사용하여 게임 개발을 지원합니다. Unity에서 C#을 사용하면 다음과 같은 기능을 활용할 수 있습니다:

더 읽어보기: https://docs.unity.com/