연산자 오버로딩(==, !=)
연산자 오버로딩 중 ==(같다), !=(다르다) 체크는 쌍으로 이루어 져야 한다.
둘 중에 하나만 존재하지 못한다.
아래의 예제 샘플은
새로운 클래스의 key라는 string변수 값이 같은지 체크하여
bool을 리턴하도록 ==, !=연산자를 오버로딩 하였다.
//새로운 클래스
public class EquipmentActor
{
public string key; //키값변수
//단순하게 아래처럼 비교하면 null 과 비교 할 수 없어서 위험하다.
//public static bool operator ==(EquipmentActor x, EquipmentActor y)
//{
// if (x.key.Equals(y.key))
// return true;
// else return false;
//}
//public static bool operator !=(EquipmentActor x, EquipmentActor y)
//{
// if (x.key.Equals(y.key))
// return false;
// else return true;
//}
//object로 바꾸어 null비교를 하고 진행한다.
public static bool operator ==(EquipmentActor x, EquipmentActor y)
{
if ((object)x == null && (object)y == null) return true;
else if (((object)x != null && (object)y != null) && x.key == y.key) return true;
else return false;
}
public static bool operator !=(EquipmentActor x, EquipmentActor y)
{
return !(x == y);
}
//근데 가장 심플한건 if비교 할때 if((object)변수 == nullptr)하는게 제일 깔끔한거 같다. 그러면 위의 object바꾸는건 다 없어질텐데...
}
'공부 > C#' 카테고리의 다른 글
C#에서의 상수 사용 - c++의 #define 같은 활용 방안 (0) | 2016.06.16 |
---|---|
C# 배열 비우기 - Array.Clear, Array.Copy, Array.Resize 이용 (0) | 2016.06.13 |
C# 람다 식 (0) | 2016.06.08 |
C# Windows Forms - 오목 (0) | 2016.05.31 |
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
C#에서의 상수 사용 - c++의 #define 같은 활용 방안
C#에도 #define은 존재 한다.
하지만 c++ 에서의 용도와는 다르다.
그중 하나가 상수처럼 사용하고자 할때
c++ 에서는
#define PI 3.141592f
와 같이
3.141592f를 계속 사용하지 않기 위해서
define을 사용할 수 있었는데
이게 C#에서는 안된다.
C#의 정의는 역시 MSDN을 찾아보는게 최고이므로
url을 남기겠다.
https://msdn.microsoft.com/ko-kr/library/bb397677.aspx
static class Constants { public const double Pi = 3.141592f; }
C#에서는 static으로 별도의 클래스를 만들고
const로 변경 할 수 없는 값을 지정해
사용하는 것을 권장함을 알아두자.
'공부 > C#' 카테고리의 다른 글
연산자 오버로딩(==, !=) (0) | 2017.05.12 |
---|---|
C# 배열 비우기 - Array.Clear, Array.Copy, Array.Resize 이용 (0) | 2016.06.13 |
C# 람다 식 (0) | 2016.06.08 |
C# Windows Forms - 오목 (0) | 2016.05.31 |
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
C# 배열 비우기 - Array.Clear, Array.Copy, Array.Resize 이용
우리들은 배열을 비우고자 한다.
byte[] recvData = new byte[10];
위와 같이 배열을 구성하고
뒤에 사이즈를 넣어주게 된다.
"이 배열은 이만큼만 쓸 것입니다"라는 의미이다.
거기에 0부터 9까지 byte를 넣었다고 생각해보자.
(int[]로 해도 됨)
그리고 01234 숫자를 없애고 싶다면 어떻게 할 것인가?
Array.Clear(recvData, 0, 5); //(배열, 시작 인덱스, 시작 인덱스 부터 지울 길이)
위와 같은 C#의 Array 클래스에 있는 Clear 함수를 사용 할 수 있을 것이다.
하지만 recvData 를 내부를 보면
0000056789 의 byte 가 들어있다.
그게 아니라 앞에 지운것은 다 없애고
56789 만 남게 하고 싶다면 어떻게 해야 하겠는가?
Array.Clear(recvData, 0, 5);
int count = 0;
for (int i = 0; i < recvData.Length; ++i)
{
if (recvData[i] == '\0')
{
++count;
}
else break;
}
byte[] recvData2 = new byte[recvData.Length - count];
Array.Copy(recvData, count, recvData2, 0, recvData2.Length); // (원본배열, 옮길 인덱스 시작 위치, 복사본 배열, 복사될 시작위치, 복사될 길이)
편리한 함수가 따로 있지 않은 것 같다.
(내가 못찾은 것일 수도 있다.)
위와 같이 '\0'이 들어간 부분을 카운트 하여 앞에서부터 길이를 재고
Array.Copy 로 다른 배열로 옮기는 것이다.
그러면 뒤에서 부터 잘라 올 수 있다.
그럼 반대로 뒤에를 날리고 앞에꺼만 보존 하여
배열 사이즈를 맞춘다면 어떻게 할까?
Array.Resize(ref recvData, recvData.Length - eraseLength); // (원본 배열 ref 꼭 붙여야 함(참조의 의미), 재조정할 사이즈)
위와 같은 Resize함수를 사용해주면
사이즈를 재조정해주면서
뒤를 없앨 수 있다.
위의 함수 들을 복합적으로 사용하면
중간 중간에 비어있는 값들도 뺄 수 있게 되니
잘 처리해보도록 하자
'공부 > C#' 카테고리의 다른 글
연산자 오버로딩(==, !=) (0) | 2017.05.12 |
---|---|
C#에서의 상수 사용 - c++의 #define 같은 활용 방안 (0) | 2016.06.16 |
C# 람다 식 (0) | 2016.06.08 |
C# Windows Forms - 오목 (0) | 2016.05.31 |
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
=>
위의 기호로 사용 되는 익명함수 기법.
"람다 식" 이라고 불린다.
c++ 11버전 부터도 추가된 기법이다.
(주의 // C++11 에서는 사용법이 다르다.)
정확한 것은 위의 url에 접근하여
한번씩 글을 읽어 보기 바란다.
간략하게 얘기 해보면
=> 왼쪽에 입력될 매개 변수가 지정되고
=> 오른쪽에서는 왼쪽의 매개변수를 사용하여 식을 적용하면
결과로서 값이 다시 매개변수로 반환되는 유용한 식이다.
제약 사항이나 다양한 사용 방법을 다 설명하긴 너무 길어지니
역시 위의 url을 클릭해서 읽어보자.
'공부 > C#' 카테고리의 다른 글
C#에서의 상수 사용 - c++의 #define 같은 활용 방안 (0) | 2016.06.16 |
---|---|
C# 배열 비우기 - Array.Clear, Array.Copy, Array.Resize 이용 (0) | 2016.06.13 |
C# Windows Forms - 오목 (0) | 2016.05.31 |
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
yield return, yield break (0) | 2016.05.24 |
C# Windows Forms - 오목
C#에서 WinForm 을 처음 다루어 보았다.
오목을 만들었다.
오목 게임 자체는 c++ Console로도 만들어봤으니
과거를 추억해가며 금방 만들었다.
직관성 있게 디자인 한 것을
바로바로 확인할 수 있으니 편했다.
[그림 1 - 결과 오목]
[그림 2 - 결과 타임 아웃]
C# 윈폼을 다룰 때 속성 창이나 이벤트 처리등은
예전 회사 다닐때 써봤던 국산 UI 툴 중
투비소프트 사의 마이플랫폼, 엑스플랫폼 을 사용 했을 때나
그 외 다른 툴 들 과도 사용 방법이 거의 비슷해서
과거가 새록새록 기억나며 재미있었다.
'공부 > C#' 카테고리의 다른 글
C# 배열 비우기 - Array.Clear, Array.Copy, Array.Resize 이용 (0) | 2016.06.13 |
---|---|
C# 람다 식 (0) | 2016.06.08 |
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
yield return, yield break (0) | 2016.05.24 |
Console 키입력 - Console.ReadKey, ConsoleKeyInfo (0) | 2016.05.12 |
소켓 통신, 웹 통신(간략 설명, 메모)
■ socket (소켓) 통신
보통 네트워크 게임에서 사용
요청이 없어도 상대에서 알려줄 수 있음
장점
-데이터를 다루는데 있어서 자유로움
-주고 받는게 맘대로 가능
단점
-소켓은 빨대라고 생각. 통신기가 바뀌면 끊김
-빨대의 최대 갯수가 정해져 있음
-웹통신 보다 안정적이지 않음
난이도 웹 통신보다 높음.
메모리에 데이터를 가지고 있을 수 있음.
상호작용 많으면 어쩔 수 없이 소켓 네트워킹을 해야 함.
============================
■ web (웹) 통신
요청을 보내야 반응이 있음
- 비연결 지향. 빨대가 없음. (내부적인 빨대는 있음. 잠깐 연결 후 짜름)
- 최대 연결 갯수가 비교적 여유
- 안정적
메모리에 데이터를 가지기 힘들다.
데이터베이스(DB)에 데이터를 가지고 처리하기에
데이터베이스를 좀 할 줄 알아야 함.
랭킹 서버만 다루면 웹 통신만으로 처리 가능.
모바일 게임에서 많이 다룸.
============================
보통 게임들은 위의 통신 기술들을 복합적으로 사용함.
RPG게임을 예로 들면
아이템을 먹었는데 나중에 보니 없어졌다고 하면
유저들의 신뢰도를 떨어뜨리게 되고 잃게 되는 경우가 큼.
이렇게 신뢰도가 중요한 데이터라고 판단되는 데이터들은 웹 통신으로 처리.
캐릭들간의 실시간 위치 정보는
조금 차이나도 괜찮다고 유저들은 생각하거나 혹은 크게 티가 안나므로
실시간 소켓 통신을 한다고 생각하면 됨.
'공부 > C#' 카테고리의 다른 글
C# 람다 식 (0) | 2016.06.08 |
---|---|
C# Windows Forms - 오목 (0) | 2016.05.31 |
yield return, yield break (0) | 2016.05.24 |
Console 키입력 - Console.ReadKey, ConsoleKeyInfo (0) | 2016.05.12 |
예외처리 - try, catch, finally, throw new Exception (0) | 2016.05.12 |
yield return, yield break
C#에 들어와서 첨 보는 구문이다.
지금껏 뭔가 만들 때는 쓸 일이 없었는데
유니티의 코루틴 관련되어서는 쓸일이 많다는 것 같다.
유니티의 코루틴은 나중에 다뤄서 보고
오늘은 C#의 yield가 붙은 구문에 대해서 살펴 보자.
C#에 대한 자세한 사항은 역시 MSDN이다.
아래의 url에 들어가서 한번 씩 살펴 보자
https://msdn.microsoft.com/ko-kr/library/9k7k7cf0.aspx
본인이 머리속으로 정리한 내용은 이러하다.
어떠한 함수 내에서 return 값을 받는 것이 있다고 해보자.
그 return은 반복문 안에 있다.
예를 들면 아래와 같다.
int 함수명()
{
int count = 0;
while(true)
{
count += 1;
return count;
}
}
위의 함수를 호출 해봤자 계속 return값은 1 밖에 안된다.
그렇다면 이제 yield return 을 사용해 보자.
yield 를 쓸때에는 반복기 인터페이스 형식이 필요하다고 나온다.
반복기 인터페이스 형식이란 것은 IEnumerable, IEnumerator 같은 인터페이스를 가르킨다.
private IEnumerable<int> Count()
{
int count = 0;
while (true)
{
count += 1;
yield return count;
}
}
public void Print()
{
foreach (int i in Count())
{
Console.WriteLine(i);
}
}
위와 같은 소스가 정~~~말 간략한 예제이다.
(찾아보면 정말 어렵게 잘쓴 코드들이 있다. 전문적인....)
Print()함수 호출하게 되면 1부터 계속 1씩 증가된 값들이 출력된다.
while (true) 이므로 1,2,3,4,5,6,~,~,~,,,,계속 출력 된다.
어떻게 1이 아니라 값이 증가가 되는 것일까?
yield return 으로 빠져 나온 구문은 현재 그 상태를 기억하고 있다.
말이 좀 애매한데
foreach 에서 계속 반복으로 Count()를 호출하고 변수 i에 넣고
Console.WriteLine(i); 를 끝나고 다시 체크 할때
Count() 의 처음 부터 다시 동작 하는 것이 아니라
yield return 을 했던 자리에서 다시 시작 되는 것이다.
즉 함수가 아예 끝... } 부분까지 도달하지 않는 이상 계속 돌리는 것이다.
위와 같은 예제 소스에서는 While( 조건문 )에 반복을 나올 수 있는 조건을 주거나
while(true){
....
if (count == 8) yield break;
....}
와 같이 yield break; 을 해주면 해당 반복을 모두 마칠 수 있다.
yield return 을 한 문장으로 정리하자면
리턴되는 위치가 저장되어 다시 호출 됐을 때 저장된 위치로부터 재시작이 될수 있다.
라고 생각 해도 되겠다.
그 것을 끝낼 수 있는 것은 yield return 할수 없이 함수 자체가 끝나거나
강제로 yield break; 해주면 된다.
yield 자체로는 위의 정의로 끝나겠지만
이게 간단치 않다.
위의 글중에 나온 인터페이스 들...IEnumerable, IEnumerator
반복기라고 하는데 이들의 차이와 정확한 사용 예...
사용 조건을 정확히 이해 하기는 아직은 힘든 것 같다.
저 인터페이스들을 class가 implement하여 구현해서 사용 할 수도 있고
IEnumerable, IEnumerator마다 구현해야 하는 함수는
각각 다르고 foreach 말고 다른 구문에서 사용하려면 어떻게 해야 하는지 등등
계속 MSDN을 읽어 봐서 이해가 되면 다음 포스팅으로 적도록 하겠다.
'공부 > C#' 카테고리의 다른 글
C# Windows Forms - 오목 (0) | 2016.05.31 |
---|---|
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
Console 키입력 - Console.ReadKey, ConsoleKeyInfo (0) | 2016.05.12 |
예외처리 - try, catch, finally, throw new Exception (0) | 2016.05.12 |
파일 로드 - FileStream, StreamReader, ReadAllText, ReadAllLines (0) | 2016.05.12 |
Console 키입력 - Console.ReadKey, ConsoleKeyInfo
//Console 키입력
ConsoleKeyInfo cKey = Console.ReadKey(true); //bool 값은 입력된 값 표시 여부로 true 일 때 표시 안함이다.
//Console.ReadKey() 는 기본 false이다. 콘솔창에 표시된다.
switch (cKey.Key) //변수.Key로 어떤 키를 입력 했는지 알 수 있다.
{
//대략 아래처럼 ConsoleKey 를 가져와 처리한다.
case ConsoleKey.LeftArrow: //방향키 왼쪽
break;
case ConsoleKey.RightArrow: //방향키 오른쪽
break;
case ConsoleKey.UpArrow: //방향키 위쪽
break;
case ConsoleKey.DownArrow: //방향키 아래쪽
break;
}
//ConsoleKey는 enum으로 되어있다. 꽤 많으나 주석 처리가 잘되어있으니
//Visual Studio에서 F12를 눌러 필요한 것을 찾아보자.
'공부 > C#' 카테고리의 다른 글
소켓 통신, 웹 통신(간략 설명, 메모) (0) | 2016.05.28 |
---|---|
yield return, yield break (0) | 2016.05.24 |
예외처리 - try, catch, finally, throw new Exception (0) | 2016.05.12 |
파일 로드 - FileStream, StreamReader, ReadAllText, ReadAllLines (0) | 2016.05.12 |
파일 저장 - FileStream, StreamWriter, WriteAllText, WriteAllLines (0) | 2016.05.12 |
예외처리 - try, catch, finally, throw new Exception
//예외처리 - try, catch, finally
//예전에 java랑 Jsp 다룰때 꽤 많이 썼었다.(try, catch 안쓰면 컴파일 에러나는 것도 꽤 있었다.)
//쉽게 생각하자.
//try - 하다가 (문제가 없어야 되는게 맞지만) 문제가 생기면
//catch - 잡는다.(문제가 없으면 잡을 것도 없다.)
//finally - 마지막으로 문제가 있든 없든 실행할 코드 - 안써도 됨.
class ExceptionTest //일부러 에러 내보기 위한 class생성
{
public int i = 10;
}
class Program
{
//함수로 에러발생이 나게 만들어 보자 - 아래의 main함수 먼저 보고 돌아오자.
static void TestDiv(int n1, int n2)
{
if(n2==0)
{
//커스텀 Exception - 내가만든 에러 메세지
throw new Exception("n2는 0이 아니어야 한다.");
}
Console.WriteLine("n1 / n2 함수");
Console.WriteLine("{0} / {1} = {2}", n1, n2, n1 / n2);
}
//메인 함수
static void Main(string[] args)
{
ExceptionTest t = null;
//예외 처리
try
{
//위험 요소가 있는 코드를 작성
Console.WriteLine("Test : {0}", t.i);
}
catch (NullReferenceException e) //특정 예외만 골라내기 - new되지 않는 class사용하려고 함
{
//try 부분에서 에러가 발생하면 catch 소스로 접근
//프로그램을 죽이지 않고 처리하기 위한 방법
Console.WriteLine("널 참조 예외가 발생");
Console.WriteLine(e.Message); //한글로 간략 오류 설명
Console.WriteLine("=======================");
Console.WriteLine(e); //예외 메세지 전체
}
//catch를 여러개 사용할 수 있는데 위에서 먼저 잡히면 아래껀 무시
catch (Exception e) //모든 예외
{
//try 부분에서 에러가 발생하면 catch 소스로 접근
//프로그램을 죽이지 않고 처리하기 위한 방법
Console.WriteLine("예외가 발생함.");
Console.WriteLine(e.Message); //한글로 간략 오류 설명
//Console.WriteLine("=======================");
//Console.WriteLine(e); //예외 메세지 전체
}
finally
{
//예외가 발생 하든 안하든
//무조건 들어와서 실행되는 영역.
Console.WriteLine("try 마지막");
}
//0으로 나눌때 에러를 발생해보자
try
{
Console.WriteLine("10/0 = ?");
//int n1 = 10 / 0; //에러 - 0으로 나눌 수 없어서 빨간줄
int n1 = 10;
int n2 = 0;
//int n3 = n1 / n2;
//Console.WriteLine("{0} / {1} = {2}", n1, n2, n3);
TestDiv(n1, n2);
}
catch(DivideByZeroException e) //0으로 나눌때 잡는 Exception
{
Console.WriteLine("0으로 나누려고 함");
Console.WriteLine(e);
}
catch (Exception e)
{
Console.WriteLine("에러!!!!!!!");
Console.WriteLine(e);
}
//catch가 개발용...테스트 할 때 포함 하면 좋지만
//성능이 그리 좋은게 아니라
//배포시에는 뺄수 있으면 빼는 것이 좋다.
}
}
'공부 > C#' 카테고리의 다른 글
yield return, yield break (0) | 2016.05.24 |
---|---|
Console 키입력 - Console.ReadKey, ConsoleKeyInfo (0) | 2016.05.12 |
파일 로드 - FileStream, StreamReader, ReadAllText, ReadAllLines (0) | 2016.05.12 |
파일 저장 - FileStream, StreamWriter, WriteAllText, WriteAllLines (0) | 2016.05.12 |
컬렉션(Collection), 제네릭 컬렉션(Generic Collection) - 예) ArrayList, List<T> (0) | 2016.05.11 |
파일 로드 - FileStream, StreamReader, ReadAllText, ReadAllLines
//파일 로드 - FileStream, StreamReader, ReadAllText, ReadAllLines
//이전 글 - 파일 저장과 대입되는 4가지 방법 이다.
private string loadData; //로드한 데이터를 담을 변수
//디렉터리 경로 지정
private const string path = "./save/test1/"; //요즘 많이 사용하는 방법 /
private const string path2 = ".\\save\\test2"; //옛날부터 디렉터리 구분하는 방법 \\
private const string path3 = @".\save\test3"; //@뒤에 있는 string은 디렉터리를 표시하는 것이라고 지정 - 최신
private void PrintLoadData()
{
Console.WriteLine("읽은 데이터는 다음과 같습니다.");
Console.WriteLine("{0}\n", loadData);
}
//로드
//1. FileStream
public void LoadFromFileStream(string fileName = "S_FileString.txt")
{
string fullpath = path + "/" + fileName; //그냥 쉽게 하려고 쓴것이다. 성능은 StringBuilder이 좋다.
try
{
//파일 스트림 생성. cs파일 상단에 using System.IO; 추가
FileStream fs = new FileStream(
fullpath,
FileMode.Open,
FileAccess.Read);
//바이트 단위로 로드
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, bytes.Length);
loadData = Encoding.UTF8.GetString(bytes);
fs.Close();
}
//파일 못찾음
catch (FileNotFoundException) //변수 없어도 됨
{
Console.WriteLine("파일을 찾지 못했습니다.");
return;
}
//디렉터리 못찾음
catch(DirectoryNotFoundException)
{
Console.WriteLine("폴더가 없습니다.");
return;
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("로딩 완료 LoadFromFileStream");
PrintLoadData();
}
//2. StreamReader
public void LoadFromStreamReader(string fileName = "S_StreamWriter.txt")
{
string fullpath = path2 + "/" + fileName;
try
{
FileStream fs = new FileStream(
fullpath,
FileMode.Open,
FileAccess.Read);
StreamReader sr = new StreamReader(fs); //스트림 생성
string line;
StringBuilder builder = new StringBuilder();
while((line = sr.ReadLine()) != null) //한줄 읽는데 null이 아니면
{
builder.Append(line); //한줄 저장
builder.Append("\n"); //개행
}
loadData = builder.ToString();
sr.Close();
fs.Close();
}
//파일 못찾음
catch (FileNotFoundException) //변수 없어도 됨
{
Console.WriteLine("파일을 찾지 못했습니다.");
return;
}
//디렉터리 못찾음
catch (DirectoryNotFoundException)
{
Console.WriteLine("폴더가 없습니다.");
return;
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("로딩 완료 LoadFromStreamReader");
PrintLoadData();
}
//3. ReadAllText
public void LoadFromReadAllText(string fileName = "S_WriteAllText.txt")
{
string fullpath = path3 + "/" + fileName;
try
{
loadData = File.ReadAllText(fullpath); //걍 모두 저장. 한줄이라 참쉽다.
}
//파일 못찾음
catch (FileNotFoundException) //변수 없어도 됨
{
Console.WriteLine("파일을 찾지 못했습니다.");
return;
}
//디렉터리 못찾음
catch (DirectoryNotFoundException)
{
Console.WriteLine("폴더가 없습니다.");
return;
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("로딩 완료 LoadFromReadAllText");
PrintLoadData();
}
//4. ReadAllLines
public void LoadFromReadAllLines(string fileName = "S_WriteAllLines.txt")
{
string fullpath = path2 + "/" + fileName;
try
{
string[] lines = File.ReadAllLines(fullpath); //라인별로 string 배열에 저장
StringBuilder builder = new StringBuilder(lines.Length); //스트링 변수의 크기를 알고 있으면 선언해주는게 좋다
foreach(var line in lines)
{
builder.Append(line);
builder.Append("\n");
}
loadData = builder.ToString();
}
//파일 못찾음
catch (FileNotFoundException) //변수 없어도 됨
{
Console.WriteLine("파일을 찾지 못했습니다.");
return;
}
//디렉터리 못찾음
catch (DirectoryNotFoundException)
{
Console.WriteLine("폴더가 없습니다.");
return;
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("로딩 완료 LoadFromReadAllLines");
PrintLoadData();
}
'공부 > C#' 카테고리의 다른 글
Console 키입력 - Console.ReadKey, ConsoleKeyInfo (0) | 2016.05.12 |
---|---|
예외처리 - try, catch, finally, throw new Exception (0) | 2016.05.12 |
파일 저장 - FileStream, StreamWriter, WriteAllText, WriteAllLines (0) | 2016.05.12 |
컬렉션(Collection), 제네릭 컬렉션(Generic Collection) - 예) ArrayList, List<T> (0) | 2016.05.11 |
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 예제소스 (0) | 2016.05.11 |