구조체
- 필드와 메소드를 가질 수 있는 등 클래스와 상당히 유사
- 데이터를 담기 위한 자료구조로 사용되기 때문에 굳이 은닉성을 비롯한 객체지향의 원칙을 구조체에
강하게 적용하지 않는 편
- 따라서 편의상 필드를 public 으로 선언하는 경우가 많음
- 클래스와 다르게 구조체는 "값 형식"
특징 | 클래스 | 구조체 |
키워드 | class | struct |
형식 | 참조형식(힙에 할당) | 값 형식(스택에 할당) |
복사 | 얕은 복사 | 깊은 복사 |
인스턴스 생성 | new 연산자와 생성자 필요 | 선언만으로도 생성 |
생성자 | 매개변수 없는 생성자 선언 가능 | 매개변수 없는 생성자 불가능 |
상속 | 가능 | 값 형식이므로 상속 불가능 |
구조체는 값 형식이다 따라서 구조체의 인스턴스는 스택에 할당되고 인스턴스가 선언된 블록이 끝나는 지점의 메모리에서 사라진다 (인스턴스 사용이 끝나면 즉시 메모리에서 사라짐 = 가비지 콜렉터를 덜 귀찮게 함)
=> 클래스에 비해 성능의 이점
구조체는 매개변수가 없는 생성자를 선언할 수 없다. 대신 구조체의 각 필드는 CLR이 기본값으로 초기화 해줌
using System;
using static System.Console;
namespace thistiscsharp
{
struct Point3D
{
public int x;
public int y;
public int z;
public Point3D(int x, int y, int z) //struct의 생성자. 반드시 매개변수가 있어야합니다.
{
this.x = x;
this.y = y;
this.z = z;
}
public override string ToString() //System.Object형식의 ToString()메소드를 오버라이딩
{
return string.Format($"{x},{y},{z}");
}
}
class MainClass
{
public static void Main(string[] args)
{
Point3D point3d; //선언만으로 인스턴스가 생성됨
point3d.x = 1;
point3d.y = 2;
point3d.z = 3;
Console.WriteLine($"{point3d.ToString()}");
Point3D point3d2 = new Point3D(10, 20, 30); //물론 생성자를 이용한 인스턴스 생성도 가능
Point3D point3d3 = point3d2; // 구조체의 인스턴스를 다른 인스턴스에 할당하면 깊은복사가 이루어짐
point3d3.z = 40;
Console.WriteLine($"{point3d2.ToString()}");
Console.WriteLine($"{point3d3.ToString()}");
}
}
}
readonly struct
변경 불가능객체
: 쓰레드 간에 동기화를 할 필요가 없기 때문에 프로그램 성능 향상이 가능하고,
버그로 인한 상태(데이터)의 오염을 막을 수 있음
- 구조체를 선언할 때 readonly만 붙이면 됨
- readonly를 이용해 구조체를 선언하면 해당 구조체의 모든 필드가 readonly로 선언되도록 강제됨
(자동으로 해주는건 아니고 일일이 수식해야함)
readonly struct ImmutableStruct
{
pulbic readonly int ImmutableField; //OK
public int MutableField; //컴파일 에러 -!
}
readonly?
readonly키워드는
1. 필드
: 한번 값을 지정하면 그 후로는 값을 변경할 수 없는 필드
2. 구조체
: readonly struct로 변경불가능 구조체 선언, => 모든 필드,프로퍼티에 일일이 readonly수식
3. 메소드
한정자 형식을 readonly로. 구조체에서만 선언가능. 이때 구조체는 readonly로 수식안해도 사용가능.
메소드에게 상태(속성-필드,프로퍼티)을 바꾸지 않도록 강제
의 3가지에 사용가능하다 (공부한것 까지론 일단 3가지)