.NET에서 구조체(struct)와 클래스(class)의 차이점

2024-07-27

값 형식 vs 참조 형식:

  • 구조체: 값 형식으로, 변수에는 값 자체가 저장됩니다. 즉, 구조체 변수를 복사하면 새로운 값의 복사본이 만들어집니다.
  • 클래스: 참조 형식으로, 변수에는 객체의 메모리 위치를 참조하는 값이 저장됩니다. 즉, 클래스 변수를 복사하면 동일한 객체를 참조하는 두 개의 변수가 생성됩니다.

메모리 할당:

  • 구조체: 스택에 할당됩니다. 스택은 메모리 공간을 빠르게 할당하고 해제하는 데 사용되지만, 메모리 누수 위험이 높습니다.
  • 클래스: 힙에 할당됩니다. 힙은 메모리 관리를 자동으로 수행하기 때문에 메모리 누수 가능성이 낮지만, 구조체에 비해 할당 및 해제 속도가 느립니다.

상속:

  • 구조체: 다른 구조체로부터만 상속받을 수 있습니다.
  • 클래스: 다른 클래스 및 구조체로부터 상속받을 수 있습니다.

기본 생성자:

  • 구조체: 기본 생성자가 자동으로 제공됩니다. 이 생성자는 모든 필드를 기본값으로 초기화합니다.
  • 클래스: 기본 생성자를 명시적으로 정의해야 합니다.

인터페이스:

  • 구조체: 인터페이스를 구현할 수 있습니다.

사용 시점:

  • 구조체: 작고 단순한 데이터 덩어리를 저장할 때 사용됩니다. 예를 들어, 좌표값을 저장하는 Point 구조체와 같습니다.
  • 클래스: 복잡한 데이터를 저장하고 다양한 기능을 제공하는 객체를 만들 때 사용됩니다. 예를 들어, 고객 정보를 저장하고 주문 처리 기능을 제공하는 Customer 클래스와 같습니다.

성능:

  • 일반적으로 구조체는 클래스보다 성능이 우수합니다. 값 복사가 참조 복사보다 빠르기 때문입니다. 하지만, 이는 데이터 크기와 복잡성에 따라 다를 수 있습니다.

선택 가이드라인:

  • 다음과 같은 경우 구조체를 사용하는 것이 좋습니다.
    • 작고 단순한 데이터 덩어리를 저장해야 할 때
    • 성능이 중요한 경우
    • 값 형식의 의미가 있는 데이터를 저장해야 할 때
  • 다음과 같은 경우 클래스를 사용하는 것이 좋습니다.
    • 복잡한 데이터를 저장해야 할 때
    • 다양한 기능을 제공하는 객체를 만들 때
    • 다른 형식으로부터 상속해야 할 때
    • 인터페이스를 구현해야 할 때

결론




.NET에서 구조체와 클래스 사용 예제

구조체 예제:

struct Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public override string ToString()
    {
        return $"({X}, {Y})";
    }
}

class Program
{
    static void Main(string[] args)
    {
        Point p1 = new Point(10, 20);
        Point p2 = p1; // 값 복사

        Console.WriteLine(p1); // (10, 20) 출력
        Console.WriteLine(p2); // (10, 20) 출력

        p1.X = 30;

        Console.WriteLine(p1); // (30, 20) 출력
        Console.WriteLine(p2); // (10, 20) 출력
    }
}

설명:

  • Point 구조체는 XY라는 두 개의 필드를 가지고 있는 2D 좌표를 나타냅니다.
  • Point 구조체에는 생성자와 ToString() 메서드가 정의되어 있습니다.
  • Main 메서드에서 Point 구조체의 두 인스턴스 p1p2를 생성합니다.
  • p2p1의 값을 복사하기 때문에 두 변수는 동일한 객체를 참조하지 않습니다.
  • p1X 값을 변경하면 p2의 값은 변경되지 않습니다.

클래스 예제:

class Person
{
    private string name;
    private int age;

    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public string Name { get { return name; } set { name = value; } }
    public int Age { get { return age; } set { age = value; } }

    public override string ToString()
    {
        return $"이름: {name}, 나이: {age}";
    }
}

class Program
{
    static void Main(string[] args)
    {
        Person p1 = new Person("홍길동", 30);
        Person p2 = p1; // 참조 복사

        Console.WriteLine(p1); // 이름: 홍길동, 나이: 30 출력
        Console.WriteLine(p2); // 이름: 홍길동, 나이: 30 출력

        p1.Age = 40;

        Console.WriteLine(p1); // 이름: 홍길동, 나이: 40 출력
        Console.WriteLine(p2); // 이름: 홍길동, 나이: 40 출력
    }
}
  • Person 클래스는 nameage라는 두 개의 필드를 가지고 있는 사람을 나타냅니다.
  • p2p1을 참조하므로 두 변수는 동일한 객체를 참조합니다.



.NET에서 구조체 대신 클래스를 사용하는 경우 고려해야 할 사항

따라서 다음과 같은 경우 클래스를 사용하는 것이 더 적합할 수 있습니다.

  • 값 형식이 아닌 의미를 가진 데이터를 저장해야 할 때: 예를 들어, 파일 경로나 URL을 저장하는 경우 값 형식보다는 참조 형식을 사용하는 것이 더 의미가 있습니다.
  • 객체 식별이 중요한 경우: 객체 식별이 중요한 경우, 객체 참조를 사용하는 클래스를 사용하는 것이 좋습니다. 예를 들어, GUI 요소나 네트워크 연결을 나타내는 객체를 저장하는 경우가 여기에 속합니다.
  • 상태 변경을 감지해야 할 때: 객체의 상태 변경을 감지해야 하는 경우 클래스를 사용하는 것이 좋습니다. 이벤트를 사용하여 객체 상태 변경을 구독할 수 있습니다.
  • 상속이 필요한 경우: 다른 클래스로부터 상속해야 하는 경우 클래스를 사용해야 합니다. 구조체는 다른 구조체로만 상속받을 수 있습니다.
  • 인터페이스를 구현해야 할 때: 인터페이스를 구현해야 하는 경우 클래스를 사용해야 합니다. 구조체도 인터페이스를 구현할 수 있지만, 일반적으로 클래스를 사용하는 것이 더 좋습니다.

성능

구조체는 일반적으로 클래스보다 성능이 우수합니다. 하지만, 이는 데이터 크기와 복잡성에 따라 다를 수 있습니다. 실제 성능 측정을 통해 어떤 형식이 더 적합한지 판단해야 합니다.

메모리 사용

구조체는 스택에, 클래스는 힙에 할당됩니다. 스택은 메모리 공간을 빠르게 할당하고 해제하는 데 사용되지만, 메모리 누수 위험이 높습니다. 힙은 메모리 관리를 자동으로 수행하기 때문에 메모리 누수 가능성이 낮지만, 구조체에 비해 할당 및 해제 속도가 느립니다.

일반적인 프로그래밍 관행

.NET 프로그래밍에서는 일반적으로 다음과 같은 경우 구조체를 사용합니다.

일반적으로 다음과 같은 경우 클래스를 사용합니다.

  • 객체 식별이 중요한 경우
  • 상태 변경을 감지해야 할 때

결론


.net class struct



C#, .NET, LINQ를 사용한 DataTable 쿼리 프로그래밍

LINQ to DataSet을 사용하여 DataTable을 쿼리할 수 있습니다.AsEnumerable() 메서드 사용: DataTable을 IEnumerable<DataRow> 인터페이스를 구현하는 개체로 변환합니다...


C#에서 기본 생성자 호출에 대한 심층 설명

C#에서 기본 생성자 호출은 객체 지향 프로그래밍의 핵심 개념인 상속과 밀접한 관련이 있습니다. 상속을 통해 만들어진 자식 클래스는 부모 클래스의 특성을 물려받게 되는데, 이때 부모 클래스의 초기화를 위해 기본 생성자를 호출하는 것이 필수적입니다...



.net class struct

C#, .NET, DateTime을 이용한 나이 계산

해결 방법:DateTime 타입 변수 선언: 생일을 저장할 DateTime 타입 변수 birthday를 선언합니다. 예시: DateTime birthday = new DateTime(1990, 1, 1);DateTime 타입 변수 선언:


C#에서 사전을 값으로 정렬하는 방법

1. Linq 사용하기LINQ(Language Integrated Query)는 C#에 내장된 기능으로, 데이터 쿼리 및 변환을 쉽게 수행할 수 있도록 합니다. 사전을 값으로 정렬하려면 다음과 같은 코드를 사용할 수 있습니다


C#, .NET 및 성능과 관련된 Type에서 새 개체 인스턴스를 만드는 방법

1. new 키워드 사용:위 코드는 MyClass 형식의 새 인스턴스를 myObject 변수에 할당합니다. new 키워드는 메모리에 새 개체를 할당하고 해당 클래스의 생성자를 호출합니다.2. Activator 클래스 사용:


C#에서 String과 string의 차이점

1. String 클래스String은 . NET Framework의 기본 문자열 클래스입니다. 문자열 데이터를 다루기 위한 다양한 메서드와 속성을 제공하며, 다음과 같은 특징을 가집니다.불변: String 객체는 생성 후 변경할 수 없습니다


Entity Framework 대 LINQ to SQL: .NET 프로그래밍 비교

1. 개요LINQ to SQL:2008년 . NET Framework 3.5에 도입된 최초의 . NET ORMSQL Server에만 국한비교적 단순하고 사용하기 쉬움Visual Studio 디자이너 도구 제공2008년