SerializableAttribute 클래스는 해당 클래스가 직렬화가 될 수 있음을 나타내며 상속될 수 없습니다. 여기서 직렬화란 객체를 저장매체에 저장하거나 바이너리의 형태로 전달하기 위해 나중에 재구성(역직렬화) 할 수 있는 형태로 변환하는 것을 의미합니다.

 

이를 통해서 객체의 상태를 원본 그대로 유지하고(영속성) 필요할 때 다시 생성할 수 있습니다. 또한, 네트워크를 통해 전달이 가능해집니다.

 

이때 직렬화의 유형은 여러 가지가 있습니다. 예를 들어 Binray, CSV, XML, JSON 등이 있습니다. 아래 예제에서는 Binray 유형을 통해 직렬화를 진행하였습니다. 여기서는 간단하게 이해만 하고 본인의 상황에 맞는 유형을 선택해 사용하면 되겠습니다.

 

이제 예제를 통해 자세히 알아보겠습니다.

 

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class Test {
   public static void Main()  {

      // Creates a new TestSimpleObject object.
      TestSimpleObject obj = new TestSimpleObject();

      Console.WriteLine("Before serialization the object contains: ");
      obj.Print();

      // Opens a file and serializes the object into it in binary format.
      Stream stream = File.Open("data.xml", FileMode.Create);
      BinaryFormatter formatter = new BinaryFormatter();

      formatter.Serialize(stream, obj);
      stream.Close();

      // Empties obj.
      obj = null;

      // Opens file "data.xml" and deserializes the object from it.
      stream = File.Open("data.xml", FileMode.Open);
      formatter = new BinaryFormatter();

      obj = (TestSimpleObject)formatter.Deserialize(stream);
      stream.Close();

      Console.WriteLine("");
      Console.WriteLine("After deserialization the object contains: ");
      obj.Print();
   }
}

// A test object that needs to be serialized.
[Serializable()]
public class TestSimpleObject  {

    public int member1;
    public string member2;
    public string member3;
    public double member4;

    // A field that is not serialized.
    [NonSerialized()] public string member5;

    public TestSimpleObject() {

        member1 = 11;
        member2 = "hello";
        member3 = "hello";
        member4 = 3.14159265;
        member5 = "hello world!";
    }

    public void Print() {

        Console.WriteLine("member1 = '{0}'", member1);
        Console.WriteLine("member2 = '{0}'", member2);
        Console.WriteLine("member3 = '{0}'", member3);
        Console.WriteLine("member4 = '{0}'", member4);
        Console.WriteLine("member5 = '{0}'", member5);
    }
}

 

크게 어려운 내용은 없습니다. TestSimpleObject 객체의 데이터들을 직렬화 하기 전에 출력하고 직렬화한 뒤 객체를 비워줍니다. 이후, 직렬화 한 데이터를 가지고 와서 역직렬화를 거친 데이터를 다시 출력하는 코드입니다. 다만, member5의 경우 [NonSerialized()] 선언을 통해 직렬화를 하지 않도록 만들었습니다. 실제 코드를 실행하면 아래와 같습니다.

 

Before serialization the object contains: 
member1 = '11'
member2 = 'hello'
member3 = 'hello'
member4 = '3.14159265'
member5 = 'hello world!'

After deserialization the object contains: 
member1 = '11'
member2 = 'hello'
member3 = 'hello'
member4 = '3.14159265'
member5 = ''

 

본문 코드에서 직렬화를 피하도록 설정한 member5를 제외한 나머지 변수들은 제대로 역직렬화 과정을 거쳐 값이 출력되는 것을 확인할 수 있습니다.

 

- 참조

1. 위키

2. Microsoft Docs

 

'프로그래밍 > C#' 카테고리의 다른 글

[C#] Boxing과 Unboxing  (0) 2021.03.15
[C#] 값형식과 참조형식의 예시  (1) 2021.03.15
[C#] var 데이터 형식  (0) 2021.03.15
[C#] Null 조건 부 연산자  (1) 2020.12.26
[C#] out, ref 키워드 살펴보기  (0) 2020.09.24
블로그 이미지

NIA1995

,

Null 조건부 연산자는 피연산자가 null이 아닌 것으로 평가되었을 때만 멤버와 요소에 접근하여 연산을 적용하고, 그렇지 않은 경우 null을 반환하는 문법입니다.

 

1. A가 null로 평가되면 A?.x 또는 A?[x]의 결과는 null입니다.

2. A가 null이 아닌 것으로 평가되면 A?.x 또는 A?[x]의 결과는 각각 a.x , a[x]의 결과와 같습니다.

 

Null 조건부 연산자는 단락 연산자로써, 조건부 멤버나 요소 접근 작업의 연결된 작업에서 null을 반환하면 나머지 작업은 실행하지 않습니다.

 

A?.B?.Do(C);
A?.B?[C];

 

위와 같은 경우에서 A가 null인 경우, B를 평가하지 않고 null을 반환, A 또는 B가 null일 경우 C를 평가하지 않고 null을 반환합니다.

 

double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)
{
    return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}

var sum1 = SumNumbers(null, 0);
Console.WriteLine(sum1);  // output: NaN

var numberSets = new List<double[]>
{
    new[] { 1.0, 2.0, 3.0 },
    null
};

var sum2 = SumNumbers(numberSets, 0);
Console.WriteLine(sum2);  // output: 6

var sum3 = SumNumbers(numberSets, 1);
Console.WriteLine(sum3);  // output: NaN

 

또한 위의 예제처럼 null 병합 연산자 ??를 사용해서 null 조건부 연산 결과가 null인 경우 다른 값을 반환할 수 있습니다.

'프로그래밍 > C#' 카테고리의 다른 글

[C#] Boxing과 Unboxing  (0) 2021.03.15
[C#] 값형식과 참조형식의 예시  (1) 2021.03.15
[C#] var 데이터 형식  (0) 2021.03.15
[C#] SerializableAttribute 클래스  (0) 2021.01.01
[C#] out, ref 키워드 살펴보기  (0) 2020.09.24
블로그 이미지

NIA1995

,

인스펙터에서 나타나는 정보들을 원하는대로 수정하려면 Editor 클래스를 상속받아 스크립트를 작성하면 됩니다. 이 때 반드시 Project Folder/Assets/Editor 경로 상에 스크립트를 저장해야 동작하게 됩니다.

 

Properties

 

1. target : 검사 대상을 Object로 반환합니다.

 

Public Methods

 

1. OnEnable : 맞춤 제작한 에디터의 인스턴스가 생성될 때 호출됩니다.

 

2. OnInspectorGUI : 인스펙터 상에 표시되는 GUI들을 맞춤 제작할 때 사용합니다.

 

Message

 

1. OnSceneGUI : Scene 상에 표시되는 GUI들을 맞춤 제작할 때 사용합니다.

블로그 이미지

NIA1995

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

마우스 커서 ON / OFF

 

Cursor.visible = true / false;

 

마우스의 커서 표시 여부를 결정합니다. 하지만 커서를 숨겨도 화면 밖으로 움직이면 벗어나는 경우가 있는데 이럴 때는 lockState에 접근해서 막아주면 됩니다.

 

Cursor.lockState = CursorLockMode.Locked; /* 마우스 위치를 중앙에서 벗어나지 못하도록 잠궈줍니다. */

Cursor.lockState = CursorLockMode.Confined; /* 게임 창 밖으로 나가는 것을 막아줍니다. */

Cursor.lockState = CursorLockMode.None; /* 마우스 커서의 제한을 풀어줍니다. (기본 옵션) */

 

 

블로그 이미지

NIA1995

,

일반적으로 인자로 오는 변수들은 메모리에서 값을 복사해서 가져오기 때문에 함수 안에서 인자의 원본 값을 변경하지 못합니다. 그러나 out 키워드, ref 키워드는 메모리의 주소를 복사하여 변수를 직접 가리킵니다. 즉, 함수 안에서 인자 원본 값을 수정할 수 있게 됩니다. 

 

따라서 기본적으로 ref, out 키워드 둘 다 C++에서 참조자의 역할을 하게 됩니다.  여기서 out 키워드는 중요한 하나의 특징을 더 가지고 있는데 out 키워드가 붙은 인자는 해당 함수가 끝나기 전에 값을 할당 받아야 합니다. 

 

이를 간단한 예제를 통해 활용하는 방법을 알아보겠습니다. / 21.01.01 수정

 

public class ItemData
{
    public int buffValue;
    
    public ItemData(int buffValue)
    {
    	this.buffValue = buffValue;
    }
    
    public void AddValue(ref int v)
    {
    	v += buffValue;
    }
}

public class Character
{
   public int agility;
   public int intellect;
   public int stamina;
   public int strength;
   
   ……….
}

 

예를 들어서 아이템이 캐릭터의 특정 스탯을 올려준다고 가정할 때 캐릭터의 다양한 스탯마다 스탯을 증가하는 함수를 만들어 줄 수는 없습니다. 이 때 ref 키워드를 사용하면 해당 메모리에 접근하여 값을 수정할 수 있게 됩니다. 따라서 ref 인자로 원하는 스탯만 넣어준다면 아이템의 효과만큼 스탯을 증가시킬 수 있습니다.

 

- 참조

1. 인생 유니티 교과서

'프로그래밍 > C#' 카테고리의 다른 글

[C#] Boxing과 Unboxing  (0) 2021.03.15
[C#] 값형식과 참조형식의 예시  (1) 2021.03.15
[C#] var 데이터 형식  (0) 2021.03.15
[C#] SerializableAttribute 클래스  (0) 2021.01.01
[C#] Null 조건 부 연산자  (1) 2020.12.26
블로그 이미지

NIA1995

,

프로그래밍을 배우면서 굳이 헷갈리게 0부터 시작하는지, 혹은 마지막 숫자를 포함하지 않는지 궁금하던 적이 한번쯤 있을 것입니다. 우리는 프로그래밍을 하면서 다양한 자료를 순회하면서 처리하게 됩니다. 이를 수학적 측면에서 구간(Interval)이라고 합니다. 구간은 "두 실수 사이의 모든 실수의 집합"을 의미합니다.

 

그리고 우리가 이러한 집합을 처리할 때 컴퓨터 과학자들이 관습적으로 사용하던 'Half-open interval', 'Zero-based numbering' 규칙을 적용하기 때문입니다.

 

그 두가지 규칙을 따로 살펴보면 아래와 같습니다.

 

1. Half-open interval은 말 그대로 구간의 양 끝 중 한 곳만 닫힌 상태의 구간을 의미합니다.

 

2. Zero-based numbering은 첫 번째 인덱스는 0부터 시작한다는 규칙입니다.

 

그렇다면 관습적으로 위 두 가지 규칙을 지켜왔는지를 이해하기 위해서는 아래 문서를 참고하시면 됩니다.

 

위키피디아 Zero-based numbering

'프로그래밍 > 일반 지식' 카테고리의 다른 글

[일반] 프로그래밍에서 DirtyFlag란?  (0) 2022.04.23
블로그 이미지

NIA1995

,