c#에서는 메모리의 저장 방식에 따라 참조형식과 값형식이 존재한다.
블록을 만나게되면 값형식의 경우 stack구조로 데이터가 하나씩 쌓이게 된다.
ex
{
int a = 40;
int b = 100;
}
참조형식 예시
{
object a= 100;
object b= 200;
}
참조형식 또한 동적으로 데이터가 할당될 때 스택영역에 차근차근 데이터가 쌓이게 되며, 스택영역에는 데이터의 주소값이 들어가고 힙에해당 주소값의 데이터가 들어가게 된다. 이후에 블록이 끝나서 사용이 다한 데이터들은 스택영역에서 지워지게되고 참조하는 값이 없는 Heap영역의 값은 나중에 GC에서 지우게된다.
<얕은 복사> Shallow Copy
클래스는 기본적으로 참조형식이다. 그렇기 때문에 복사에 주의가 필요하다
class Monster
{
public int hp;
public int damage;
public Monster(int hp, int damage)
{
this.hp = hp;
this.damage = damage;
}
}
static void Main()
{
Monster myMonster = new Monster(100, 5);
Monster otherMosnter = myMonster;
otherMonster.hp = 200;
Console.WriteLine($"myMonster HP : {myMonster.hp}"); //output 200
Console.WriteLine($"otherMonster HP : {otherMonster.hp}"); //output 200
}
//객체를 하나만 생성하고 가르키는 참조변수는 두개를 설정해서 하나의 체력만 변경해도 둘다 변경되는 문제가 발생.
cf) **c#에서는 System내에 ICloneable 인터페이스가 존재한다.**
DeepCopy의 개념과 비슷하지만 인터페이스를 상속한후 clone이라는 메소드만 오버라이딩 해주면 코드의 호환성을 높일 수 있다.
```cs
namespace wcm{
public static void Main(string[] args){
}
class Monster : ICloneable
{
public int hp;
public int damage;
public Monster(int hp, int damage)
{
this.hp = hp;
this.damage = damage;
}
public Monster Clone()
{
Monster newMonster = new Monster();
newMonster.hp = this.hp;
newMonster.damage = this.damage;
return newMonster;
}
}
C# 에서는 소멸자의 사용을 지양한다.
소멸자를 명시적으로 구현할경우 GC가 클래스의 족보를 타고올라가 Finalize()메소드를 호출하기에 응용프로그램의 성능저하를 초래할 가능성이 높다.
힙영역에 값을 넣는게 스택영역에 값을 넣는거보다 무거운 이유?
스택영역에는 정적으로 데이터가 할당 되기에 예측이 가능하지만 동적할당을 하는 힙영역 데이터는
언제 만들어지고 메모리에 올라갈지 예측이 불가능하기 때문에 데이터의 추가를 위한 입력값이 들어올 때마다 운영체제에게 특정 메모리값을 할당하라고 명령을 주어야 하기 때문에 더 오버헤드가 많이 발생한다.
헷갈림을 방지하기 위한 저장방식
struct SimpleStruct
{
public bool Married;
}
class PersonClass
{
public int Age;
public SimpleStruct Info;
}
class Program
{
static void Main(string[] args)
{
int i = 10;
PersonClass pc = new PersonClass { Age = 20,
Info = new SimpleStruct { Married = true } };
}
}
-> class는 참조형식이기에 class내의 struct 또한 힙영역에 저장된다.
struct SimpleStruct
{
public int Age;
}
class Program
{
static void Main(string[] args)
{
int[] intArr = { 10, 20 };
SimpleStruct[] ssArr = new SimpleStruct[3];
}
}
3.참조형식Class안에 또다른 class들의 배열을 정의 할 경우 ?
Reference)
https://www.sysnet.pe.kr/2/0/12624?pageno=109
https://developer-talk.tistory.com/50