슈퍼 마리오가 애니메이션으로 나온다는 소식을 처음 접했을 때는 과연 영화로 슈퍼 마리오의 스토리와 액션을 재밌게 풀어나갈 수 있을까 반신반의했다. 하지만 그런 걱정은 예고편을 보고 나서 사라졌다. 박진감 넘치는 액션과 익숙한 배경음악만으로 내 가슴은 두근거리기 시작했다.

 

2023 04 30 

강남의 메가박스에서 슈퍼 마리오 브라더스를 감상했다. 생각보다 사람들이 많이 없어서 한적하게 영화를 즐길 수 있었다.

 

우선 영화 감상부터 말하자면 캐릭터부터 배경, 음악, 스토리 모두 잘만들어진 작품이었다. 정교한 애니메이션으로 캐릭터들 하나하나 개성을 잘 살리고 표정과 액션을 잘 묘사했다. 배경으로 보이는 여러 요소들도 원작의 팬들이라면 반가워할 만큼 디테일하게 담아냈다. 배경 음악과 효과음 또한 영화에 어울리게 보정을 해서 튀지 않으면서도 원본을 잘 살려 반가움과 추억을 느낄 수 있었다. 

 

스토리는 원작의 느낌을 잘 녹여냈고 126분이라는 시간동안 지루할 틈 없이 매끄럽게 쭈욱 이어나간다.

너무 유치하지도 않으면서 개연성은 잘살렸고 나이 상관없이 모두 즐길 수 있는 유머들도 좋았다. 물론 원작을 전혀 몰라도 보는데 지장이 없는 작품이지만 나처럼 어린 시절에 슈퍼 마리오에 대한 추억이 있다면 더 몰입되고 반가운 요소들과 사운드 때문에 상영 내내 설레면서 보게 될 것 같다.

 

엔딩 크레딧이 모두 올라가고 나오는 쿠키 영상에서 상영관의 모든 사람들이 반가움의 감탄을 뱉어냈다. 그렇게 다음 후속작에 대한 떡밥까지 던지면서 영화는 마무리되었다. 

 

귀여운 펭귄

 

가정의 달인 5월에 가장 어울리는 영화라 생각한다.

이번편에서 자세하게 다루지 않은 부분들이 다음 편에 어떻게 나올지 기대되면서 후속작을 기다려본다.

728x90
반응형

'Life' 카테고리의 다른 글

치토스 맥앤치즈  (0) 2023.10.23
사이버 나무  (0) 2023.05.11
베트남 콘삭 커피  (0) 2023.04.09
티스토리 단축키  (0) 2023.03.30
장 줄리앙 전시회 - 그리고 거기  (1) 2023.03.27

에디터 버전 : 2021.3.28f1 (LTS)

 

Adaptive Performance

모바일 장치와 같은 저사양의 플랫폼에서 자동으로 프레임률을 관리하고 최적화할 수 있도록 기능을 제공한다.

기능이 활성화되면 하드웨어 자원을 최대한 활용하여 최적의 성능을 얻을 수 있다. 

 

기능을 사용하기 위해서는 Adaptive Performance 패키지부터 설치해야 한다. 아래의 인스톨 버튼을 클릭하면 해당 패키지의 최신 버전의 설치가 진행된다.

 

패키지 설치가 끝나면 다음과 같이 화면이 변경된다.

 

Adaptive Performance Docs

공식 문서부터 살펴본다.

view documentation

 

해당 패키지의 설명은 이렇다.

 

Adaptive Performance allows you to get feedback about the thermal and power state of your mobile device and react appropriately.
(Adaptive Performance를 사용하면 모바일 장치의 발열과 전원 상태에 대한 피드백을 가지고 적절하게 대응할 수 있다.)

 

여기서 전원 상태란 모바일 장치의 전력 상태를 의미한다.

(전력이 낮은지, 충분한지 또는 충전 중인지 등의 상태)

For example, you can create applications that react to temperature trends and events on the device, to ensure constant frame rates over a longer period of time and prevent thermal throttling.
(장치의 온도 추세나 이벤트에 반응해서 일관된 프레임률을 장기간 유지하고 열 제한을 방지하는 애플리케이션을 만들 수 있다.)

 

온도 추세는 모바일 장치의 온도 변화를 뜻한다. 모바일 장치는 사용자가 앱을 실행하거나 다양한 작업을 수행할 때 온도가 상승할 수 있다. 이벤트는 앱의 실행과 종료, 배터리 잔량 변화, 충전 상태 변화, 네트워크 상태, 알림, 회전 등과 같이 여러 상태 변화를 뜻한다. 

 

열 제한은 모바일 장치가 과열될 때 발생하는 현상으로 온도가 높아짐에 따라 장치의 성능이 저하되거나 충전이 중단되는 등의 문제가 발생한다. 따라서 열 제한을 방지한다는 것은 장치의 온도가 올라가서 열 제한을 발생시켜 성능이 저하되지 않도록 온도추세와 이벤트에 반응하여 프레임률 관리를 통해서 모바일 장치의 과열을 방지하는 것을 의미한다.

 

Thermal Throttling 

 

Provider

Adaptive Performance를 활용하기 위해서는 정보를 제공할 장치가 필요하다. 이 장치를 Provider라고 하며 빌드 대상에 맞는 Provider가 제공된다. PC 플랫폼인 경우 별도의 Provider는 제공되지 않으며 Simulator라는 가상 장치를 사용할 수 있다. Simulator는 Adaptive Performance 패키지가 설치될 때 함께 다운로드되며 Provider의 경우 선택될 때 패키지 설치가 진행된다. 하지만 선택을 해제해도 해당 패키지가 삭제되진 않으며 삭제하고 싶은 경우 패키지 매니저를 사용해야 한다.

 

 

Simulator = PC, Provider = Mobile (android, ios) 

 

 

728x90
반응형

is

주어진 값이 특정 클래스 혹은 구조체의 인스턴스인지 아닌지를 판별하는 연산자이다.

즉, is 연산자는 해당 값이 주어진 클래스 또는 구조체로부터 상속되었거나 해당 구조체와 일치하는지를 판별하는 데 사용된다.

 

object obj = "Hello World!";
if (obj is string)
{
	Console.WriteLine("obj is a string");
}

 

is 키워드는 obj 변수가 string 타입에 해당하는지 검사한다.

만약 obj가 string 타입이면 로그가 출력되는데 string은 object의 파생 클래스이기 때문에 object 형식으로 형변환이 가능하며 해당 조건문은 true로 로그가 출력이 된다.

 

as

참조 타입의 변수에서 형식 변환을 수행하는 연산자이다.

as 연산자를 사용하면 형식 변환 작업을 수행하면서 실패한 경우 null을 반환한다.

 

object obj = "Hello World!";
string str = obj as string;
if (str != null)
{
	Console.WriteLine(str,ToUpper());
}
else
{
	Console.WriteLine("obj is not a string");
}

 

object 타입인 obj를 as를 사용해서 string으로 형변환을 하였다. 

당연히 object는 string으로 형변환이 가능하기 때문에 해당 결과는 true로 결과가 출력된다.

 

is 만 사용할 경우 암시적으로 형변환이 일어나는데 이때 예외처리 에러가 발생할 수 있다. as를 사용해서 형변환을 시도한 결과를 null 예외처리를 할 수 있기 때문에 is와 as는 함께 많이 사용된다.

 

sizeof

피연산자의 크기를 바이트 단위로 계산하여 반환하는 연산자이다.

이 연산자는 컴파일 타임에 실행되며 모든 유형과 식을 피연산자로 취급이 가능하다.

// sizeof(type)
int size = sizeof(int);

sizeof 연산자는 스택에 메모리를 할당할 때 유용하다. 정확한 크기를 알고 있는 배열을 만들 때 sizeof 연산자를 사용하여 각 요소의 크기를 계산하고 이를 기반으로 배열의 크기를 계산할 수 있다.

 

하지만 sizeof 연산자는 값 형식의 객체에 대해서만 사용할 수 있으며 참조 형식에 대해서는 사용이 불가능하다.

참조 타입의 경우 인스턴스 크기를 얻기 위해서는 Marshal.Sizeof() 메서드를 사용할 수 있지만 이 메서드는 해당 인스턴스가 저장된 메모리의 크기를 반환하므로 실제 인스턴스의 크기와는 다를 수 있다.

 

typeof 

특정 타입의 System.Type 객체를 반환하는데 이를 통해 코드에서 지정한 타입에 대한 정보를 얻을 수 있다. 

컴파일 타임에 타입을 검사하기 때문에 코드의 안정성과 가독성을 높일 수 있으며 객체의 타입을 확인하고 이에 따라 적절한 작업을 수행하는 코드를 작성할 수 있다.

 

// typeof(Type)
Type t = typeof(int);

해당 타입의 System.Type 객체를 반환한다. C#에서 사용되는 모든 타입에 대한 정보를 담고 있으며 해당 타입에 대한 모든 메타데이터를 포함하고 있다.

 

t 변수는 int 타입의 System.Type 객체를 참조하게 되며 이를 통해 int 타입에 대한 정보를 얻을 수 있다.

이외에도 다양한 타입에 대한 정보를 typeof 연산자를 통해 얻을 수 있다.

 

 

 

stackalloc

고정 크기의 메모리 블록을 동적으로 할당하기 위해서 사용한다.

메모리 할당과 해제가 매우 빠르고 GC에 의해서 관리되는 힙 메모리를 사용하지 않으므로 애플리케이션의 성능을 향상할 수 있다. C/C++의 alloca() 함수와 비슷한 역할을 한다. 

 

하지만 alloca과 다르게 stackalloc은 호출된 함수의 실행이 종료될 때 자동으로 메모리가 해제되게 된다.

 

Span<int> numbers = stackalloc[] { 1, 2, 3, 4, 5 };
var idx = numbers.IndexOfAny(stackalloc[] { 2, 4, 6, 8 });
Console.WriteLine(idx);

 

포인터 형식으로도 메모리 할당이 가능하다.

 

unsafe
{
	int length = 3;
    int* numbers = stackalloc int[lenth];
    for (var i = 0; i < length; i++)
    {
    	numbers[i] = i;
    }
}

포인터 형식을 사용할 경우 지역 변수에서만 stackalloc을 사용하여 변수를 초기화 할 수 있다.

 

루프 내부에서는 stackalloc을 사용하지 않아야하며 루프 외부에서 메모리 블록을 할당하고 루프 내부에서 사용하는 방식으로 가야 한다.

 

스택에서 사용 가능한 메모리는 제한적이기 때문에 너무 많은 메모리를 할당하게 되면 스택오버플로우 에러가 발생한다.

이 문제를 방지하기 위해서는 할당하려는 버퍼의 크기가 특정 한도 내에서만 할당되도록 제한을 두어야 한다.

const int MaxStackLimit = 1024;
Span<byte> buffer = inputLength <= MaxStackLimit ? 
					stackalloc byte[inputLength] : new byte[MaxStackLimit];

입력한 버퍼의 크기가 최대 크기보다 작으면 입력한 만큼의 버퍼를 할당하고 최대를 벗어날 경우에는 최대크기만큼만 버퍼를 할당하도록 한다.

 

새로 할당된 메모리는 반드시 사용 전에 초기화가 필요하다. 이때 모든 형식의 기본값으로 설정할 수 있는 Span<T>.Clear 메서드를 사용할 수 있다.

 

 

checked/unchecked

정수 연산 시 overflow 발생 여부를 처리하는 데 사용한다.

기본적으로 C#에서 정수형 연산은 오버플로우가 생기면 예외가 발생한다. 이 예외를 처리하기 위해서는 try-catch 문을 사용해야 하는데 이는 코드를 복잡하게 만들 수 있기 때문에 이런 상황에서는 checked와 unchecked 키워드를 사용할 ㅅ ㅜ있다.

 

int x = int.MaxValue;
int y = 1;

checked
{
	int z = x + y;
}

unchecked
{
	int z = x + y;
}

 위 코드는 int의 최댓값이 1을 더하는 것으로 OverflowException이 발생하는 코드이다.

이때 checked를 사용하면 계산과정에서 overflow가 나기 때문에 예외가 발생한다.

unchecked를 사용할 경우에는 overflow가 발생해도 예외를 발생시키지 않고 결과를 진행한다.

int a = int.MaxValue;
int b = unchecked(a + 1);
int c = checked(a + 1); // System.OverflowException 예외 발생

 

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# 라이브러리 Collections, Generic  (0) 2023.05.16
C# 객체지향 프로그래밍  (0) 2023.05.15
C# Method Parameter 키워드  (0) 2023.04.27
C# Namespace 키워드  (0) 2023.04.27
C# 멤버 명시 키워드 : this  (0) 2023.04.25

params

메서드의 매개 변수로 배열을 받을 수 있게 해주는 키워드이다.

params 키워드를 사용하면 메서드 호출 시 각각의 인자를 전달해서 배열형식으로 전달할 수 있다.

 

만약 배열이나 리스트와 같은 타입을 인수로 전달해야 하는 경우 리스트나 배열로 선언해서 값을 넣어줘야 한다.

public void Main(string[] args)
{
	int[] arrI = new int[4]{1,2,3,4}
    MyMethod(arrI);
}

public void MyMethod(int[] values){}

 

 

이럴 때 호출할 함수의 매계변수를 params로 선언하면 따로 배열로 묶어줄 필요가 없어진다.

 

public void Main(string[] args)
{
	MyMethod(1, 2, 3, 4);
}

public void MyMethod(params int[] values)
{
	foreach (int value in values)
    {
    	Console.WriteLine(value);
    }
}

 

 

params 키워드를 통해서 인자를 각각의 인덱스에 값을 넣는 형식으로 받아서 사용이 가능하다.

 

ref

reference 즉, 참조를 뜻하는 키워드이다.

이 키워드를 사용해서 값 타입을 참조 타입처럼 사용할 수 있다.

 

static void Swap(int a, int b)
{
	int temp = a;
    a = b;
    b = temp;
}

인자로 받은 두 값을 서로 바꾸는 메서드이다.

int는 값 형식으로 값의 복사만 이루어지기 때문에 위 메서드는 a와 b의 값이 바뀌지 않는다.

 

이때 ref 키워드를 사용하면 참조를 하게 되므로 본래의 변수들의 값이 수정된다,

static void Swap(ref int a, ref int b)
{
	int temp = 4;
    a = b;
    b = temp;
}

이렇게 ref 키워드를 사용해서 메서드를 정의하게 되면 호출하는 곳에서도 ref 키워드를 붙여서 인자를 전달해야 한다.

 

int x = 1;
int y = 2;
Swap(ref x, ref y);

C++의 포인터와 비슷한 개념이다.

하지만 포인터는 메모리 주소를 가리키는 변수이고 ref는 메모리 위치를 직접 가리키는 것이 아닌 해당 객체에 대한 참조를 가리키게 된다.

 

따라서 ref 키워드를 사용하면 참조형식 변수를 함수에 전달하여 함수 내에서 해당 변수가 참조하는 메모리 위치를 직접 조작할 수 있다. 이를 통해 함수 내에서 해당 변수가 가리키는 객체를 직접 수정하는 것이 가능하다.

 

out 

메서드에서 값을 반환하는 것 외에도 메서드 호출 이후에 값을 전달할 수 있는 방법을 제공한다,

즉 out 키워드를 사용하면 메서드 내부에서 매개변수 값을 수정할 수 있고, 수정된 값을 호출한 곳에서 가져다 쓸 수 있다.

 

키워드는 메서드의 매개변수 앞에 붙여서 사용한다. 

public void Calculate(int x, int y, out int sum, out int product)
{
	sum = x + y;
    product = x * y;
}

Calculate 메서드는 x, y 두 매개변수를 받는다. 그리고 out 키워드를 사용해서 sum, product 두 개의 매개변수를 추가로 받고 있다.

 

해당 메서드 내부에서는 전달받은 x, y를 이용해서 sum, product를 계산한 후 각각의 매개변수에 값을 할당한다.

이후 메서드를 호출할 때 sum, product를 담을 변수를 선언하고 이 변수를 매개변수로 넘겨주어야 한다.

 

int a = 5;
int b = 10;
int totalSum = 0;
int totalProduct = 0;

Calculate(a, b, out totalSum, out totalProduct);

Console,WriteLine(totalSum + " " + totalProduct);

 

메서드가 호출되면 Calculate 내부에서는 전달받은 a와 b의 가지고 각각 totalSum의 값과 totalProduct의 값을 계산하여 저장한다. 따라서 함수의 호출 이후에 totalSum과 totalProduct의 값은 계산 결과가 담기게 된다.

 

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# 객체지향 프로그래밍  (0) 2023.05.15
C# Operator 키워드  (0) 2023.04.27
C# Namespace 키워드  (0) 2023.04.27
C# 멤버 명시 키워드 : this  (0) 2023.04.25
C# 상위 멤버 접근 키워드 : base  (0) 2023.04.25

Namespace

네임스페이스는 다른 식별자와 구분하기 위한 식별자의 집합을 의미한다.

즉, 클래스, 구조체, 인터페이스, 델리게이트, enum 등의 데이터 형식, 메서드, 변수 등을 구별하기 위한 컨테이너 역할을 한다. 

 

예를 들어 클래스명 같은 경우 일반적으로 흔히 사용하는 이름으로 작명한 경우 다른 패키지를 설치하여서 사용하다 보면 동일한 클래스명으로 인해서 충돌이 발생할 수 있다. 이럴 때 클래스를 자신만의 네임스페이스로 지정해서 구분해 두면 이름이 중복되더라도 namespace.class와 같이 구분해서 접근되기 때문에 에러를 방지할 수 있다.

 

public class MyClass{}

namespace MyScript
{
	public class MyClass{}
}
// 네임스페이스로 인해 동일한 이름의 두 클래스는 구분 된다.

 

MyScript 네임스페이스로 싸여진 MyClass를 사용하기 위해서는 MyScript에서 사용할 것임을 명시해야 한다.

 

using

코드에서 다른 네임스페이스를 가져오기 위해 사용된다.

네임스페이스로 싸인 클래스를 사용하기 위해서는 해당 네임스페이스를 명시한 뒤에 그 내부의 클래스에 접근이 가능하다.

 

namespace MyScript
{
	public class MyClass{}
}

public void Main(string[] args)
{
	MyScript.MyClass() myClass = ...
}

 

만약 네임스페이스로 싸여진 클래스의 사용이 빈번해지게 되면 매번 명시해 주는 것이 번거롭고 코드의 가독성을 떨어뜨리게 된다.

 

이때 using을 통해서 사용할 네임스페이스를 전역으로 선언할 수 있다.

 

using MyScript;

~

public void Main(string[] args)
{
	MyClass myClass = ... // using으로 인해서 MyScript의 MyClass임을 알 수 있다.
}

 

그럼에도 동시에 동일한 클래스명을 가지게 되는 경우에는 코드 앞에 네임스페이스를 명시해주어야 한다.

 

operator

연산자 오버로딩을 정의하는 데 사용되는 키워드이다. 

산술, 비교, 논리 등의 연산자를 재정의하여 다른 연산을 수행하도록 한다. 

예를 들어 내가 만든 타입의 경우 내장 연산자에는 정의되어있지 않기 때문에 계산이 불가능한데 이때 오버로딩을 해서 내가 만든 타입을 연산자로 처리하고 결과를 리턴할 수 있다.

 

public static MyClass operator +(MyClass a, MyClass b)
{
	// add MyClass a and b
    return result;
}

public void Main(string[] args)
{
	MyClass myClass1 = new MyClass();
    MyClass myClass2 = new MyClass();
    
    // 오버로딩한 내용으로 결과를 반환받게 된다.
    MyClass result = myClass1 + myClass2;
}

내가 만든 클래스 타입의 MyClass 두 개를 + 연산하기 위해서 + 연산자를 오버로딩했다.

원하는 결과를 얻기 위해서는 내부에서 필요한 동작을 구현하면 MyClass 결과를 return 받을 수 있다.

 

extern alias

다른 어셈블리를 참조할 때 사용되는 지시어이다.

일반적으로 프로젝트에서는 하나 이상의 어셈블리를 참조해야 하는데 두 개 이상의 어셈블리가 같은 이름을 가지고 있는 경우 이를 구분하기 위해서 extern alias를 사용할 수 있다.

 

extern alias A1;
extern alias A2;

A1::SomeNamespace.SomeClass someObjcet = new A1::SomeNamespace.SomeClass();
A2::SomeNamespace.SomeClass anotherObjcet = new A2::SomeNamespace.SomeClass();

A1과 A2는 각각 어셈블리의 별칭으로 이를 이용해서 어셈블리의 이름을 지정할 수 있다. 이렇게 구분지은 어셈블리는 동일한 이름을 가지고 있더라도 참조할 때 충돌하지 않는다.

 

:: operator

:: 연산자는 extern alias 지시어를 사용해 참조된 어셈블리 내의 형식을 참조하기 위해서 사용한다.

System 네임스페이스에 있는 COnsole 클래스를 사용하고자 할 때 System.Console로 사용할 수 있지만 다른 어셈블리에 있는 System 네임스페이스의 Console을 사용하고자 할 때는 extern alias 지시어를 사용한 구분이 필요하다.

 

extern alias aliasName;
aliasName::System.Console.WriteLine("Hello World");

여기서 aliasName은 다른 어셈블리에서 사용할 alias 이름을 지정하는 데 사용된다.

:: 연산자는 aliasName과 System.Console을 구분하는 데 사용한다.

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# Operator 키워드  (0) 2023.04.27
C# Method Parameter 키워드  (0) 2023.04.27
C# 멤버 명시 키워드 : this  (0) 2023.04.25
C# 상위 멤버 접근 키워드 : base  (0) 2023.04.25
C# 구조체 키워드 : struct  (0) 2023.04.25

this

인스턴스 특정

현재 인스턴스를 가리키는 기능을 한다.

주로 멤버 메서드나 생성자에서 인스턴스 변수를 참조할 때 사용한다.

 

class Person {
    private string name;
    private int age;

    public Person(string name, int age) {
        this.name = name;
        this.age = age;
    }

    public void PrintInfo() {
        Console.WriteLine("Name: " + this.name);
        Console.WriteLine("Age: " + this.age);
    }
}

이와 같은 경우 this 키워드는 동일한 이름의 name과 age를 멤버와 매개변수를 구분하는 데 사용된다.

PrintInfo 내에서는 this를 사용하지 않고 호출해도 되지만 일관성을 유지하기 위해 사용하는 등 개발자의 선호도에 따라 사용여부가 다르다.

 

 

생성자 호출

다른 생성자를 호출할 때 사용할 수 있다.

class Person {
    private string name;
    private int age;

    public Person(string name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(string name) : this(name, 0) {
    }

    public void PrintInfo() {
        Console.WriteLine("Name: " + this.name);
        Console.WriteLine("Age: " + this.age);
    }
}

위와 같이 두 개의 오버로딩된 생성자가 선언되었을 때 string name 매개변수만 받는 생성자의 경우 호출될 때 Person(string name, int age) 생성자를 호출하며 이때 age 값을 0으로 호출하는 동작이 수행된다.

 

인덱서

인덱서는 클래스나 구조체 등의 객체를 배열처럼 인덱싱할 수 있게 해주는 것으로 대괄호 안에 인덱스를 전달하여 객체의 멤버 변수나 속성 값을 가져오거나 설정할 수 있다.

 

public class MyList
{
    private string[] _data = new string[10];

    public string this[int index]
    {
        get => _data[index];
        set => _data[index] = value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyList list = new MyList();
        list[0] = "Hello";
        list[1] = "World";
        Console.WriteLine(list[0]); // "Hello" 출력
        Console.WriteLine(list[1]); // "World" 출력
    }
}

this 키워드로 정의된 인덱서는 string 형식의 배열 _data 멤버 변수를 instance [indexer]와 같이 바로 접근하여 사용할 수 있다. 

 

인덱서를 사용하지 않을 경우에는 해당 멤버에 접근하기 위해서 별도의 public 프로퍼티나 메서드 또는 _data를 public으로 선언해야 한다.

 

 

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# Method Parameter 키워드  (0) 2023.04.27
C# Namespace 키워드  (0) 2023.04.27
C# 상위 멤버 접근 키워드 : base  (0) 2023.04.25
C# 구조체 키워드 : struct  (0) 2023.04.25
C# 문자열 키워드 : string  (0) 2023.04.25

base

상위 클래스로부터 파생된 클래스에서 사용할 수 있는 키워드로 상위 클래스의 멤버에 액세스 할 때 사용된다.

예를 들어 상위 클래스에서 정의된 멤버를 파생 클래스에서 다시 구현할 때 base 키워드를 사용하면 상위 클래스의 멤버에 접근할 수 있다.

 

public class Parent{
	virtual public void CallFunc(){
    	Console.WriteLine("Parent Call");
    }
}

public class Child : Parent{
	override public void CallFunc(){
    	base.CallFunc();
        Console.WriteLine("Child Call");
    }
}

Child child = new Child();
child.CallFunc();
// Parent Call, Child Call 모두 출력됨

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# Namespace 키워드  (0) 2023.04.27
C# 멤버 명시 키워드 : this  (0) 2023.04.25
C# 구조체 키워드 : struct  (0) 2023.04.25
C# 문자열 키워드 : string  (0) 2023.04.25
C# 정수형 키워드 : int, long, short ...  (0) 2023.04.25

struct

값 형식을 나타내는 키워드이다.

struct로 정의된 데이터 타입은 클래스와 비슷한 멤버를 가질 수 있지만 다른 특징이 있다.

 

클래스와 차이

struct는 클래스와 달리 상속이나 인터페이스 구현 등의 기능을 제공하지 않으며 struct는 메모리에 적재되며 개체의 인스턴스화를 할 수 있다. 또한 struct는 기본적으로 stack에 할당되어 heap 메모리를 사용하지 않기 때문에 일반적인 값 형식을 나타내기 위해서 사용된다.

 

struct는 변수에 값을 할당할 때 복사가 일어나게 된다. 예를 들어 struct로 정의된 Point 타입의 변수에 값을 할당하면 해당 값을 복사하여 새로운 메모리 공간에 저장한다.

 

struct Point
{
	public int X;
    public int Y;
}

Point p1 = new Point{X = 10, Y = 20};
Point p2 = p1;	// 이때 p1의 값 전체가 복사되어 p2에 저장된다.

구조체가 메모리에 할당될 때 데이터 멤버들 사이에는 일정한 간격을 두고 배치된다. 

이 간격을 Padding이라고 하며 데이터 멤버의 크기와 정렬을 고려해 계산된다. 이는 구조체 전체 크기가 미리 예측 가능하기 위해서이며 이 크기는 구조체 전체 크기 합에 패딩을 합한 값이다.

 

패딩은 구조체의 크기를 불필요하게 늘리기도 하므로 크기를 최소화하기 위해서는 큰 데이터를 먼저 선언하고 뒤에 작은 데이터들이 선언되도록 멤버들을 크기에 따라 정렬하는것이 좋다. 이렇게 구조체를 제대로 이해하고 사용하기 위해서는 각 타입들의 크기와 패딩의 존재에 대해 정확한 이해가 필요하다.

 

 

 

 

 

728x90
반응형

string

문자열을 나타내는 데이터 타입이다. 문자열은 큰 따옴표로 묶인 문자들의 집합으로 표현된다.

 

string greeting = "Hello World!";

 

string은 다른 기본 데이터 타입과 다르게 참조형으로 System.String 클래스의 인스턴스이다. 따라서 string 변수에는 문자열의 주소가 저장되는데 이로 인해 문자열에 변경이 생기면 새로운 문자열 인스턴스가 생성이 된다.

 

string 타입은 null 값을 가질 수 있으며 이때는 아직 초기화되지 않은 것으로 간주된다.

string str = null;
// str 접근시 초기화 먼저 하라는 컴파일 에러 발생

 

728x90
반응형

정수형

정수형을 표현하는 데이터 타입에는 대표적으로 int가 있고 그 외에 long, short... 등이 있다.

일반적인 상황에서 모두 int로 표현이 가능하기 때문에 가장 많이 사용된다.

 

하지만 int로 표현할 수 있는 크기를 벗어난 특별한 경우도 있기 때문에 long이 존재한다.

long은 int 보다 더 큰 정수 범위를 저장할 수 있다.

 

반대로 저장할 정수값이 작은 경우에는 굳이 int를 사용하지 않아도 되기 때문에 더 적은 공간을 차지하는 short 정수형도 있다.

 

양의 정수

만약 저장할 데이터가 항상 양의 정수라면 굳이 음의 정수까지 저장하기 위한 변수의 크기를 할당할 필요가 없다.

따라서 unsigned를 붙여서 uing, ulong, ushort 정수형의 양의 범위만 저장할 수 있도록 크기를 사용할 수 있다.

 

 

그 외의 특징으로는 CPU가 정수 계산에 대해서 최적화되어 있기 때문에 소수점 계산보다 훨씬 빠르게 계산이 가능하다.

또한 부동 소수점 숫자와 비교하여 더 작은 메모리를 사용하기 때문에 대규모 데이터 세트를 처리할 때 중요한 요소가 된다.

 

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# 구조체 키워드 : struct  (0) 2023.04.25
C# 문자열 키워드 : string  (0) 2023.04.25
C# 열거형 키워드 : enum  (0) 2023.04.25
C# 문자 저장 키워드 : char  (0) 2023.04.25
C# 데이터 처리 키워드 : byte, sbyte  (0) 2023.04.25

+ Recent posts