Boxing과 Unboxing을 최소화하라

Boxing은 값 형식 (value type)을 참조 형식 (reference type)으로 변경하는 것이다.
Boxing을 수행하면 힙 상에 새로운 reference type 객체가 생성되고 value type의 객체가 가지고 있던 값이 reference type 객체 내부로 복사된다.
새로 생성된 reference type 객체는 내부적으로 value type 객체의 복사본을 포함하고, value type에서 제공하였던 interface를 그대로 재구현한다.

Unboxing은 참조 형식 (reference type)을 값 형식 (value type)으로 변경하는 것이다.
만약 reference type 객체 내부에 포함된 value type 객체의 값을 얻고자 시도하면 복사본을 만들어서 돌려준다.

Console.WriteLine(“Numbers: {0}, {1}, {2}”, 10, 20, 30);
Console.WriteLine()은 System.Object의 배열을 인자로 받는데, 정수들은 모두 value type이기때문에 value type의 인자로 전달하기 위해서는 reference type으로 boxing이 수행된다.
Boxing과 Unboxing 동작은 필요시 자동적으로 일어나며, 이 과정에서 컴파일러는 어떠한 경고도 발생시키지 않는다. WriteLine(…)을 호출할 때에는, 아래와 같이 value type을 string type instance로 변경하는 것이 좋다.
Console.WriteLine(“Numbers: {0}, {1}, {2}”, 10.ToString(), 20.ToString(), 30.ToString());
이 코드는 string type을 사용하기 때문에 value type들은 더이상 System.Object 로 변경되지 않는다.

HW1

단국대학교 멀티미디어공학과 HCI프로그래밍2 (2016년 가을학기) 실습

과목코드 : 300890

강사 : 박경신

날짜: 2016년 9월 12 일

 

– 실습번호 : HW1 (Due by 9/26)

– 실습제목 : enum, if/switch, do/while, for, read/write, nullable

– 실습요약 : 도형의 겉넓이와 부피 구하기 (SurfaceAreaVolumeCalculator)

– 준비자료 :

http://math.about.com/od/formulas/ss/surfaceareavol.htm

 

– 실습문제

  1. SurfaceAreaVolumeCalculator 클래스 작성
  2. enum Geometry { SPHERE=1, CONE=2, CYLINDER=3, RECTANGULAR_PRISM=4, SQUARE_PYRAMID=5, ISOSCELES_TRIANGULAR_PRISM=6 }
  3. double CalculateSurfaceArea(Geometry? type)은 도형(SPHERE/CONE/..)에 따라 겉넓이(Surface Area) 계산. double CalculateVolume(Geometry? type)은 도형(SPHERE/CONE/..)에 따라 부피(Volume)을 계산.
  4. Geometry? GetUserInputGeometry()은 콘솔창 사용자 입력에서 도형(SPHERE/CONE/..) 판별. double GetUserInputDouble()은 콘솔창 사용자 입력에서 double 값이 아니면 다시 재입력.                                                       void GetUserInputAdditionalInformation(Geometry? type)는 콘솔창 사용자 입력에서 각 도형마다 추가적인 정보를 요청하여 입력.
  5. + 예시: 선택한 도형 (e.g. SPHERE/CONE), 그에 따른 추가적인 입력을 받음. (e.g., 구의 반지름/radius, 원뿔의 반지름/radius와 높이/height)
    + while 문을 사용하여 잘못된 입력일 경우, 다시 사용자 입력을 받음.

  6. void Print()는 각 도형마다 도형의 겉넓이와 부피 값을 콘솔창에 출력
  7. +for(int i=1; i<=10; i++)를 사용하여 크기에 따른 각 도형의 넓이를 표로 출력함.

  8. 본인의 원하는 메소드나 루틴을 더 추가한다. 예를 들어 다른 도형의 넓이(또는 부피) 계산 등. 위의 코드로 프로그램을 작성하고, 실행 화면과 코드를 첨부하시오.

Enumerate an enum

Enum.GetValues method returns an array that contains a value for each member of the enumType enumeration.

https://msdn.microsoft.com/en-us/library/system.enum.getvalues(v=vs.110).aspx

enum Gender { Male=100, Female=200 };

// PrintAllGender()는 Male=100, Female=200 출력

public void PrintAllGender ()

{

foreach (Gender g in Gender.GetValues(typeof(Gender)))

{

Console.WriteLine(“{0}={1}”, g, (int)g);

}

}

// PrintByGender(..) 는 Male이면 남자, Female이면 여자 출력

public void PrintByGender (Gender g)

{

switch (g)

{

case Gender.Male:

Console.WriteLine(“남자”);

break;

case Gender.Female:

Console.WriteLine(“여자”);

break;

default:

Console.WriteLine(“중성자??”);

break;

}

}

Tuple vs KeyValuePair

static Tuple<int, int> GetDivideQuotientRemainder(int a, int b)

{

return new Tuple<int, int>((a / b), (a % b));

}
static KeyValuePair<int, int> GetDivideQuotientRemainder2(int a, int b)

{

return new KeyValuePair<int, int>((a / b), (a % b));

}
static void GetDivideQuotientRemainder3(int a, int b, out int q, out int r)

{

q = (a / b);
r = (a % b);

}

static void Main(string[] args)
{

var value = GetDivideQuotientRemainder(23, 4);
Console.WriteLine(“q = {0} r = {1}”, value.Item1, value.Item2);

var value2 = GetDivideQuotientRemainder2(23, 4);
Console.WriteLine(“q = {0} r = {1}”, value2.Key, value2.Value);

int q = 0;
int r = 0;
GetDivideQuotientRemainder3(23, 4, out q, out r);
Console.WriteLine(“q = {0} r = {1}”, q, r);

}

Tuple (C# 4.0)

튜플은 여러 개의 멤버를 가지는 데이터 구조임 (멤버는 8개까지 가능).
C++의 std::pair 형식과 비슷함.
C#의 KeyValuePair<Tkey, TValue>는 struct 이고, Tuple은 class 임.

var p = new Tuple<string, int>(“HCI”, 2015);
// Item1, Item2, …, Item7, Rest (the final property)
Console.WriteLine(“p={0} {1}”, p.Item1, p.Item2);

// Create() factory method can construct from a 1-tuple to an 8-tuple
var p1 = new Tuple<int, string, double>(1, “hello”, 3.14);
var p2 = Tuple.Create(2, “hci”, 0.001); // Tuple<int, string, double>

// For higher than 8 items, use nested tuple
var p3 = new Tuple<int, int, int, int, int, int, int, Tuple<int, int>>(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9));
Console.WriteLine(“8th={0} 9th={1}”, p3.Rest.Item1, p3.Rest.Item2);

// Use tuple for method return

Tuple<int, int>GetDivideQuotientRemainder(int a, int b)

{

return new Tuple<int, int>( (a/b), (a%b));

}

var value = GetDivideQuotientRemainder(23, 4)

Console.WriteLine(“q={0} r={1}”, value.Item1, value.Item2);

int => string vs string => int

// integer => string type conversion
int i = 10;                    // 10
string j = i.ToString(); // “10”

// string => integer type conversion
string x = “123”;          // “123”
int y = Convert.ToInt32(x); // 123 (integer로 변환이 가능한 경우만 변환 가능 그 외엔 run-time exception error)
int z = Int32.Parse(x); // 123 (integer로 변환이 가능한 경우만 변환 가능 그 외엔 run-time exception error)
int w;
bool success = Int32.TryParse(x, out w); // 123 (integer로 변환이 가능한 경우만 변환 가능 그 외엔 w=0)

Convert.ToInt32() vs Int32.Parse() vs Int32.TryParse()

http://www.codeproject.com/KB/cs/AgileWare_Convert_Int32.aspx

Convert.ToInt32(string s)는 내부적으로 Int32.Parse(string s)을 불러서 string을 32-bit signed integer로 변환시켜주는 메소드

string s1 = 1234″;
string s2 = 1234.65″;
string s3 = null;
string s4 = 123456789123456789123456789123456789123456789″; 
intresult;
bool success; result = Convert.ToInt32(s1); //— 1234
result = Convert.ToInt32(s2); //— FormatException 
result = Convert.ToInt32(s3); //— 0 
result = Convert.ToInt32(s4); //— OverflowException

Int32.Parse(string s)는 strng을 32-bit signed integer로 변환시켜주는 메소드
그러나 만약 s가 null일 경우 ArgumentNullException을 냄
또한 s가 integer가 아닐 경우 FormatException을 냄
또한 s가 integer의 MinValue또는 MaxVale를 넘칠 경우 OverflowException을 냄

result = Int32.Parse(s1); //— 1234 
result = Int32.Parse(s2); //— FormatException 
result = Int32.Parse(s3); //— ArgumentNullException 
result = Int32.Parse(s4); //— OverflowException



Int32.TryParse(string s, out int i)는 string을 32-bit signed integer로 변환하여 out 에 보내주는 메소드로 성공하면 true를 반환
따라서 만약 s가 null일 경우 ArgumentNullException을 내지않고 false와 out으로 0을 반환
또한 s가 integer가 아닐 경우 FormatException을 내지않고 false와 out으로 0을 반환
또한 s가 integer의 MinValue또는 MaxVale를 넘칠 경우 OverflowException을 내지않고 false와 out으로 0을 반환

success = Int32.TryParse(s1, out result); //— success => true; result => 1234 
success = Int32.TryParse(s2, out result); //— success => false; result => 0 
success = Int32.TryParse(s3, out result); //— success => false; result => 0 
success = Int32.TryParse(s4, out result); //— success => false; result => 0