공부/C#

이것이 C#이다 Chapter 03 데이터 보관하기

bokob 2024. 2. 18. 18:34

3.1 다양한 데이터의 종류

C#은 크게 기본 데이터 형식(Primitive Type)과 복합 데이터 형식(Complex Data Type)을 지원

그와 동시에 값 형식, 참조 형식으로 분류 가능

 

3.2 변수

'담을 데이터 타입에 따라 크기를 갖는 공간'

// (데이터 형식) (식별자)
int x;

선언(Declare): 식별자라는 이름으로 변수 생성 

초기화(Initialization): 변수에 최초의 데이터를 할당하는 것

C#은 초기화를 강제

 

리터럴

Literal은 '문자 그대로의' 라는 뜻을 가진 형용사

컴퓨터 과학에서 리터럴(Literal)은 고정값을 나타내는 표기법을 의미

int a = 3;          // 변수: a, 리터럴: 3
string s = "안녕"	  // 변수: s, 리터럴: "안녕"

 

3.3 값 형식과 참조 형식

값 형식(Value Type)

  • 변수가 값을 담는 데이터 타입
  • 값 형식의 변수는 스택에 저장
  • 코드 블록 안에서 생성된 모든 값 형식의 변수들은 코드 블록을 닫는 중괄호를 만나면 메모리에서 제거

참조 형식(Reference Type)

  • 변수가 값 대신 값이 있는 위치(참조)를 담는 데이터 타입
  • 참조 형식의 변수는 힙과 스택을 함께 이용한다. 데이터를 직접 저장하는 대신 실제 데이터가 저장된 메모리의 주소를 '참조' 한다고 해서 '참조 형식'이다.
  • 데이터를 더 이상 참조하지 않으면 가비지 컬렉터(Garbage Collector)가 수거
  • 힙 영역에는 데이터를 저장하고 스택영역에는 데이터가 저장된 힙 메모리의 주소를 저장

 

3.4 기본 데이터 타입

  • C#이 제공하는 기본 데이터 타입에는 모두 15가지
  • 숫자 형식, 논리 형식, 문자열 형식, 오브젝트 타입

 

숫자 데이터 형식

C#은 15가지 기본 데이터 타입 중 12가지가 숫자 데이터 타입(Numeric Type) 거기서도 정수, 부동 소수, 소수 로 나뉜다.

 

1. 정수 타입

정수 데이터를 담기 위해 사용

12가지 숫자 타입 중 9가지가 정수 타입

데이터 타입 설명 크기(바이트) 범위
byte 부호 없는 정수 1(8비트) 0 ~ 255
sbyte signed byte
정수
1(8비트) -128 ~ 127
short 정수 2(16비트) -32,768 ~ 32,767
ushort unsigned short
부호 없는 정수
2(16비트) 0 ~ 65,535
int 정수 4(32비트) -2,147,483,648 ~ 2,147,483,647
uint unsigned int
부호없는 정수
4(32비트) 0 ~ 4,294,967,295
long 정수 8(64비트) -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
ulong unsigned long
부호 없는 정수
8(64비트) 0 ~ 18,446,744,073,709,551,615
char 유니코드 문자 2(16비트)  

 

int a = 1_000_0000 // 큰 정수를 타이핑할 때 자릿수 구분자(_)를 원하는 곳에 넣어주면 보기 편함

byte b = 240;
byte c = 0b1111_0000; // 2진수 리터럴
byte d - 0xF0; // 16진수 리터럴

 

2. 부동 소수점 타입

뜰 부, 움직일 동 의 부동 소수점

  • 소수점을 표현하기 위해 일부 비트를 사용하여 같은 크기의 정수 타입과 같은 크기의 수를 표현할 수 없다.
  • 산술 연산 과정이 정수 타입보다 복잡해서 느리다.
데이터 타입 설명 크기(바이트) 범위
float 단일 정밀도 부동 소수점 4(32비트) -3.402823e38 ~ 3.402823e38
double 복수 정밀도 부동 소수점 8(64비트) -1.79769313486232e308 ~ 1.79769313486232e308

float a = 3.1415f // 직접 할당하려면 f 를 붙여줘야한다. 안붙이면 double로 인식

 

decimal

데이터 타입 설명 크기(바이트) 범위
decimal 29자리 데이터를 표현할 수 있는 소수 16(128비트) ± 1.0 x 10e-28 ~ ± 7.9 x 10e28
// m 을 안붙이면 double로 인식한다.
decmial c = 3.1415_9265_3589_7932_38846_2643_3832_79m;

decimal 보다 큰 범위를 다루려면 직접 데이터 타입을 정의해야한다.

 

3. 문자 형식과 문자열 타입

char 는 정수 타입이다. 숫자에 대응하는 유니코드를 이용해 문자를 다루는 것이다.

문자 하나를 작은따옴표('')로 묶어서 사용한다.

문자가 이어져 있는 것을 '문자열'이라 한다. 'string' 을 이용하는데, 정해진 크기나 범위가 정해져 있지 않다.

큰따옴표("")로 묶어서 사용한다.

char a = '안';
string b = "녕하세요";
string c ="""
!
?
^
""";

 

4. 논리 타입

참, 거짓 을 다룬다.

데이터 타입 설명 크기(바이트) 범위
bool 논리 형식 1(8비트) true, false

 

5. object 타입

C# 에서의 모든 데이터는 object를 상속받게 해 어떤 데이터든 담을 수 있다.

object a = 123;
object b = 3.14f;
object c = "안녕";

 

박싱과 언박싱

object 타입은 참조 타입이기 때문에 힙에 데이터를 할당한다.

object 타입은 값 타입의 데이터를 힙에 할당하기 위한 '박싱(Boxing)' 기능을 제공한다.

object 타입에 값 타입의 데이터를 할당하려 하면 박싱을 수행해서 해당 데이터를 힙에 할당한다.

힙에 있던 값 타입 데이터를 값 타입 데이터에 다시 할당할 때는 박싱된 값을 꺼내 값 타입 변수에 저장하는 '언박싱(Unboxing)' 을 해야한다.

int a = 123;
object b = (object)a; // a에 담긴 값을 박싱해서 힙에 저장
int c = (int)b; // b에 담긴 값을 언박싱해서 스택에 저장

 

데이터 형식 바꾸기

다른 데이터 타입으로 변환하는 것

  1. 크기(표현 범위)가 서로 다른 정수 타입 사이의 변환
  2. 크기(표현 범위)가 서로 다른 부동 소수점 타입 사이의 변환
  3. 부호 있는 정수 타입과 부호 없는 정수 타입 사이의 변환
  4. 부동 소수점 타입과 정수 타입 사이의 변환
  5. 문자열과 숫자 사이의 변환

1. 크기가 서로 다른 정수 형식의 변환

작은 정수 타입에서 큰 정수 타입으로 옮길 때는 문제가 없다.

반대의 경우에는 오버플로우가 발생할 수 있다.

 

2. 크기가 서로 다른 부동 소수점 타입 사이의 변환

부동 소수점 타입의 특성상 오버플로가 존재하지 않는다.(IEEE 754 표준 때문에)

다만 정밀성에 손상을 입을 수 있는 문제가 있다.

float나 double은 소수를 2진수로 메모리에 보관한다. 이것을 다른 타입으로 변환하려면 10진수로 복원 후, 다시 2진수로 변환해서 기록하게 된다. 2진수로 표현하는 소수는 완전하지 않다.

float a = 69.6875f;
Console.WriteLine("a : {0}", a);

double b = (double)a;
Console.WriteLine("b : {0}", b);
Console.WriteLine("69.6875 == b : {0}", 69.6875 == b); // true 이다. True로 출력됨

float x = 0.1f;
Console.WriteLine("x : {0}", x);

double y = (double)x;
Console.WriteLine("y : {0}", y);

Console.WriteLine("0.1 == y : {0}", 0.1 == y) // false 이다. False로 출력됨

 

3. 부호 있는 정수 형식과 부호 없는 정수 형식 사이의 변환

int x = -30;
Console.WriteLine(x); // -30 출력

uint y = (uint)x; // 언더플로 발생
Console.WriteLine(y); // 4294967266 출력

 

4. 부동 소수점 타입과 정수 타입 사이의 변환

부동 소수점 타입의 변수를 정수 타입으로 변환하면 소수점 아래는 버리고 소수점 위만 남긴다.

float a = 0.9f;
int b = (int)a;
Console.WriteLine(b);

 

5. 문자열을 숫자로, 숫자를 문자열로

정수 계열 타입, 부동 소수점 타입에 'Parse()' 메소드가 있다. 숫자로 변환할 문자열을 넘기면 숫자로 변환해준다.

int a = int.Parse("12345");
float b = float.Parse("123.45");

 

숫자 데이터 타입을 문자열로 바꾸는 것은 'ToString()' 메소드를 이용하는 것도 있다.

int c = 12345;
string d = c.ToString();

flaot e = 123.45;
string f = e.ToString();

 

3.5 상수와 열거 형식

상수(Constant), 열거 형식(Enumerator)은 변수와 달리 안에 담긴 데이터를 절대 바꿀 수 없는 메모리 공간이다.

상수와 열거 형식을 변수 대신 상요하면 컴파일러가 소스 코드를 컴파일할 때 프로그래머의 실수를 잡아 알려주고, 결국 프로그램의 버그도 줄여준다.

 

상수

const int a = 3;
const double b = 3.14;
const string c = "abcdef";

변수와 똑같이 사용할 수 있지만, 한 번 선언하고 난 후엔 데이터를 변경할 수 없다.

 

열거 형식

같은 범주에 속하는 상수를 여러 개 선언할 때 유용.

열거 형식도 상수이긴 하지만 'const' 키워드를 사용하지 않고 그 대신 'enum' 키워드를 이용

using System;

namespace PracticeCSharp
{
    class Program
    {
        // enum 열거_형식명 : 기반자료형 {상수1, 상수2, ...}
        // 기반자료형(byte, sbyte, short, ushort, int, uint, long, ulong)
        enum NumLong : long {One, Two}
        // 기반자료형을 생략할 경우 컴파일러가 int를 기반자료형으로 사용
        // 원하는 값을 할당 가능, 값을 할당하면 그 다음 요소들 부터 이전 요소에 1을 더한 값이 할당된다.
        enum NumInt{One, Two = 2, Three}

        static void Main(string[] args)
        {
            // 열거 형식을 이용해 변수를 만들 수 있다.
            NumInt result = NumInt.One;
        }
    }
}

 

3.6 Nullable 타입

Null(비어 있는) + able(~될 수 있는)

변수에 할당된 메모리 공간을 비워둘 수 있다.

int? a = null;
float? b = null;
double? c = null;

 

모든 Nullable 타입은HasValue와 Value 두 가지 속성을 갖고 있다.

HasValue 는 해당 변수가 값을 갖고 있는지 또는 그렇지 않은지를 나타낸다.

Value 속성은 변수에 담겨 있는 값을 나타낸다.

int? a = null;
Console.WriteLine(a.HasValue); // a는 null 이므로 False 출력

a = 37;
Console.WriteLine(a.HasValue); // a는 37을 갖고 있으므로 True 출력
Console.WriteLine(a.Value); // 37을 출력

 

Nullable 타입을 사용할 때는 HasValue 속성을 확인하거나  null 과 같은지를 비교하여 변수가 비어 있는지 확인하는 것이 필요하다.

 

3.7 var

C#은 변수나 상수에 대해 깐깐하게 타입 검사를 하는 강력한 형식의 언어(String Typed Language) 이다.

따라서 프로그래머의 실수를 줄여주는 장점이 있다.

반면, 약한 형식 검사는 단점만 있는 것이 아니다. 코드를 작성하는 단계에서는 더 편리하다.

'var' 를 이용해 약한 타입 검사를 하는 언어의 편리함도 지원한다. 컴파일러가 자동으로 해당 변수의 타입을 지정해준다.

단, var 키워드를 이용해서 변수를 선언하려면 반듣시 선언과 동시에 초기화해줘야 한다.

var a = 3; // a는 int 타입
var b = "Hello"; // b는 string 타입

 

var는 지역 변수로만 사용할 수 있다. 클래스의 필드를 선언할 때는 반드시 명시적 타입을 선언해야 한다.

클래스의 필드는 선언과 같이 초기화하지 않는 경우가 많다. (생성자로 초기화하는 경우가 대부분)

따라서 var 키워드로 필드를 선언하면 컴파일러가 무슨 타입인지 파악할 수 없다.

 

(번외) C#에서는 전역 변수를 지원하지 않는다.

 

var와 object의 차이는 CLR이 코드를 실행할 때 var 로 선언되었는지 눈치채지 못한다. object는 눈치챈다.

 

3.8 공용 타입 시스템

C#의 이 모든 데이터 타입 체계는 사실 C# 고유의 것이 아니다. 공용 타입 시스템(CTS, Common Type System) 이라는 .NET의 타입 체계 표준을 그대로 따르고 있다.

즉, C#이 갖고 있는 기본 데이터 타입과 복합 데이터 타입, 값 타입과 참조 타입을 아우르는 모든 체계는 공용 타입 시스템에서 온 것이다.

공용 타입 시스템은 .NET 언어라면 반드시 따라야 하는 데이터 타입 표준이다.

도입 이유는 .NET 언어끼리 서로 호환성을 갖게 하기 위해서다.

클래스 이름(CTS 타입) C# 타입 C++ 타입 비주얼 베이직 타입
System.Byte byte unsigned char Byte
System.SByte sbyte char SByte
System.Int16 short short Short
System.Int32 int int 또는 long Integer
System.Int64 long __int64 Long
System.UInt16 ushort unsigned short UShort
System.UInt32 uint unsigned int 또는 unsigned long UInteger
System.UInt64 ulong unsigned __int64 ULong
System.Single float float Single
System.Double double double Double
System.Boolean bool bool Boolean
System.Char char wchar_t Char
System.Decimal decimal Decimal Decimal
System.IntPtr 없음 없음 없음
System.UIntPtr 없음 없음 없음
System.Object object Object* Object
System.String string String* String

CTS 타입은 각 언어에서 코드에 그대로 사용 가능하다.

 

3.9 문자열 다루기

1. 문자열 안에서 찾기

메소드 설명
IndexOf() 현재 문자열 내에서 찾으려고 하는 지정된 문자 또는 문자열의 위치를 찾는다.
LastIndexOf() 현재 문자열 내에서 찾으려고 하는 지정된 문자 또는 문자열의 위치를 뒤에서부터 찾는다.
StartsWith() 현재 문자열이 지정된 문자열로 시작하는지를 평가한다.
EndsWith() 현재 문자열이 지정된 문자열로 끝나는지를 평가한다.
Contains() 현재 문자열이 지정된 문자열을 포함하는지를 평가한다.
Replace() 현재 문자열에서 지정된 문자열이 다른 지정된 문자열로 모두 바뀐 새 문자열을 반환한다.
using static System.Console;

namespace PracticeCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            string greeting = "Good Morning";

            WriteLine(greeting);
            WriteLine(greeting);

            // IndexOf
            WriteLine("IndexOf 'Good' : {0}", greeting.IndexOf("Good"));
            WriteLine("IndexOf 'o' : {0}", greeting.IndexOf('o'));

            // LastIndexOf
            WriteLine("LastIndexOf 'Good' : {0}", greeting.LastIndexOf("Good"));
            WriteLine("LastIndexOf 'o' : {0}", greeting.LastIndexOf('o'));

            // StartsWith()
            WriteLine("StartsWith 'Good' : {0}", greeting.StartsWith("Good"));
            WriteLine("StartsWith 'Morning' : {0}", greeting.StartsWith("Morning"));

            // EndsWith()
            WriteLine("EndsWith 'Good' : {0}", greeting.EndsWith("Good"));
            WriteLine("EndsWith 'Morning' : {0}", greeting.EndsWith("Morning"));

            // Contains()
            WriteLine("Contains 'Evening' : {0}", greeting.Contains("Evening"));
            WriteLine("Contains 'Morning' : {0}", greeting.Contains("Morning"));

            // Replace()
            WriteLine("Replaced 'Morning' with 'Evening' : {0}",
                greeting.Replace("Morning", "Evening"));
        }
    }
}

 

2. 문자열 변형하기

메소드 설명
ToLower() 현재 문자열의 모든 대문자를 소문자로 바꾼 새 문자열을 반환한다.
ToUpper() 현재 문자열의 모든 소문자를 대문자로 바꾼 새 문자열을 반환한다.
Insert() 현재 문자열의 지정된 위치에 지정된 문자열이 삽입된 새 문자열을 반환한다.
Remove() 현재 문자열의 지정된 위치로부터 지정된 수만큼의 문자가 삭제된 새 문자열을 반환한다.
Trim() 현재 문자열의 앞/뒤에 있는 공백을 삭제한 새 문자열을 반환한다.
TrimStart() 현재 문자열의 앞에 있는 공백을 삭제한 새 문자열을 반환한다.
TrimEnd() 현재 문자열의 뒤에 있는 공백을 삭제한 새 문자열을 반환한다.
using static System.Console;

namespace PracticeCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            WriteLine("ToLower() : '{0}'", "ABC".ToLower());
            WriteLine("ToUpper() : '{0}'", "abc".ToUpper());

            WriteLine("Insert() : '{0}", "Happy Friday!".Insert(5, " Sunny"));
            WriteLine("Remove() : '{0}", "I Don't Love You".Remove(2, 6));

            WriteLine("Trim() : '{0}'", " No Spaces ".Trim());
            WriteLine("TrimStart() : '{0}'", " No Spaces ".TrimStart());
            WriteLine("TrimEnd() : '{0}'", " No Spaces ".TrimEnd());
        }
    }
}

 

3. 문자열 분할하기

메소드 설명
Split() 지정된 문자를 기준으로 현재 문자열을 분리한 다음 분리한 문자열의 배열을 반환한다.
SubString() 현재 문자열의 지정된 위치로부터 지정된 수만큼의 수만큼의 문자로 이루어진 새 문자열을 반환한다.
using System;
using static System.Console;

namespace PracticeCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            string greeting = "Good morning.";

            WriteLine(greeting.Substring(0, 5)); // "Good"
            WriteLine(greeting.Substring(5));    // "morning"
            WriteLine();

            string[] arr = greeting.Split(
                new string[] { " " }, StringSplitOptions.None);
            WriteLine("World Count : {0}", arr.Length);

            foreach (string element in arr)
                WriteLine("{0}", element);
        }
    }
}

 

4. 문자열 서식 맞추기

문자열의 일정한 틀과 모양을 갖추는 것

C#은 문자열 서식화에 사용할 수 있는 간편한 두 가지를 제공한다. 두 방법 모두 서식화된 새로운 문자열을 만들어낸다.

  • string 타입의 Format() 메소드
  • 문자열 보간

Format() 메소드

Console.WriteLine()에서 사용하는 문자열 틀에 입력하는 {0}, {1}, ... 을 일컬어 '서식 항목'(Format Item) 이라고 한다.

서식 항목에 추가 옵션을 입력함으로써 더 다양한 서식화가 가능하다.

// {첨자(서식 항목의 첨자), 맞춤(왼쪽/오른쪽 맞춤): 서식문자열(변환 서식 지정 문자열)}
Console.WriteLine("Total : {0, -7: D}", 123); // 첨자:0, 맞춤:-7, 문자열:D

 

string.Format() 을 이용한 세 가지 서식화

  • 왼쪽/오른쪽 맞춤
  • 숫자 서식화
  • 날짜 및 시간 서식화

1) 왼쪽/오른쪽 맞춤

서식 항목의 맞춤 옵션을 지정하면 해당 서식 항목이 차지할 공간의 크기를 선택할 수 있고, 그 공간 안에서 왼쪽 또는 오른쪽에 데이터를 할당할지 결정할 수 있다.

string result = string.Format("{0,-10}DEF", "ABC");
// result : "ABC       DEF"

result = string.Format("{0,10}DEF", "ABC");
// result : "       ABCDEF"

 

using System;
using static System.Console;

namespace PracticeCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            string fmt = "{0,-20}{1,-15}{2,30}";

            WriteLine(fmt, "나라", "분류", "상품명");
            WriteLine(fmt, "대한한국", "전자기기", "스마트폰");
            WriteLine(fmt, "나이지리아", "음식", "옥수수");
        }
    }
}

 

2) 숫자 서식화

서식 항목의 옵션중 서식 문자열에 의해 결정된다.

서식 문자열에 사용할 수 있는 서식 지정자(Format Specifier)

표준 숫자 서식 문자열 - .NET | Microsoft Learn

서식 지정자 대상 서식 설명
D 10진수 입력된 수를 10진수로 서식화
ex)
WriteLine("{0:D}", 255); // 255
WriteLine("{0:D}", 0xFF); // 255
X 16진수 입력된 수를 16진수로 서식화
ex)
WriteLine("{0:X}", 255); // 0xFF
WriteLine("{0:X}", 0xFF); // 0xFF
N 콤마(,)로 묶어 표현한 수 입력된 수를 콤마로 구분하여 출력
ex)
WriteLine("{0:N}", 123456789) // 123,456,789.00
F 고정 소수점 입력된 수를 고정 소수점 타입으로 서식화
ex)
WriteLine("고정 소수점: {0:F}", 123.45); // 123.45
E 지수 입력된 수를 지수 표기로 서식화
ex)
WriteLine("공학: {0:E}", 123.456789); // 1.234568E+002

서식 문자열은 서식 지정자와 함께 '자릿수 지정자'(Precision Specifier'를 사용할 수 있다.

서식문자열이 Axx라면 A는 서식 지정자, xx는 자릿수 지정자의 꼴로 사용하면 된다.

이때 자릿수 지정자는 0에서 99까지의 값을 입력할 수 있다.

using System;
using static System.Console;

namespace PracticeCSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            // D : 10진수
            WriteLine("10진수: {0:D}", 123); // WriteLine(string.Format("10진수: {0:D}", 123)); 과 동일
            WriteLine("10진수: {0:D5}", 123);

            // X : 16진수
            WriteLine("16진수: 0x{0:X}", 0xFF1234);
            WriteLine("16진수: 0x{0:X8}", 0xFF1234);

            // N : 숫자
            WriteLine("숫자: {0:N}", 123456789);
            WriteLine("숫자: {0:N0}", 123456789); // 자릿수 0은 소수점 이하를 제거

            // F : 고정 소수점
            WriteLine("고정 소수점: {0:F}", 123.45);
            WriteLine("고정 소수점: {0:F5}", 123.456);

            // E : 공학용
            WriteLine("공학: {0:E}", 123.456789);
        }
    }
}

 

3) 날짜 서식화

날짜와 시간을 표현하기 위해서는 DateTime 클래스가 필요하다.

제어판의 [국가 및 지역] 설정에서 지역을 변경하지 않아도 System.Globalization.CultureInfo 클래스로 날짜 및 시간 서식을 조작할 수 있다.

서식 지정자 대상 서식 설명
y 연도 yy: 두 자릿수 연도(2023-03-04 23:18:22 -> 23)
yyyy: 네 자릿수 연도(2023-03-04 23:18:22 -> 2023)
M M: 한 자릿수 월(2023-01-08 21:03:07 -> 1)
MM: 두 자릿수 월(2023-01-08 21:03:07 -> 01)
d d: 한 자릿수 일(2023-01-08 21:03:07 -> 8)
dd: 두 자릿수 일(2023-01-08 21:03:07 -> 08)
h 시(1~12) h: 한 자릿수 시(2023-01-08 21:03:07 -> 9)
hh: 두 자릿수 시(2023-01-08 21:03:07 -> 09)
H 시(0~23) H: 한 자릿수 시(2023-01-08 21:03:07 -> 21)
HH: 두 자릿수 시(2023-01-08 21:03:07 -> 21)
m m: 한 자릿수 분(2023-01-08 21:03:07 -> 3)
mm: 두 자릿수 분(2023-01-08 21:03:07 -> 03)
s s: 한 자릿수 초(2023-01-08 21:03:07 -> 7)
ss: 두 자릿수 초(2023-01-08 21:03:07 -> 07)
tt 오전/오후 tt: 오전/오후(2023-01-08 11:03:07 -> 오전,
                    2023-01-08 21:03:07 -> 오후)
ddd 요일 ddd:  약식 요일(2023-03-04 23:18:22 -> 토)
dddd: 전체 요일(2023-03-04 23:18:22 -> 토요일) 

 

CultureInfo 클래스를 이용해 문화권에 맞는 시간 출력한 것

CultureInfo ciKo = new CultureInfo("ko-KR");

// 2023-03-04 오후 11:18:22 (토)
WriteLine(dt.ToString("yyyy-MM-dd tt hh:mm:ss (ddd)", ciKo));

CultureInfo ciEn = new CultureInfo("en-US");

// 2023-03-04 PM 11:18:22 (Sat)
WriteLine(dt.ToString("yyyy-MM-dd tt hh:mm:ss (ddd)", ciEn));

 

4) 문자열 보간

C# 6.0에 새로 도입된 기능

문자열 틀 앞에 '$'  기호를 붙이고 서식 항목에 첨자 대신 식이 들어간다.

$"텍스트{<보간식>[,길이][:서식]}텍스트{...}..."

  • 보간식: 보통 인스턴스의 이름을 지정하지만 출력할 객체를 반환하는 식을 지정할 수도 있다.
  • 길이: 길이 옵션, 서식 항목의 [맞춤]과 같다.
  • 서식: 서식 항목의 [서식 문자열]과 같다.

string.Format() vs 문자열 보간

string.Format() 문자열 보간
WriteLine("{0}, {1}", 123, "엄준식"); WriteLine($"{123}, {"엄준식"}");
WriteLine("{0,-10:D5}", 123); WriteLine($"{123, -10:D5}");
int n = 123;
string s = "엄준식";
WriteLine("{0}, {1}, n, s");
int n = 123;
string s = "엄준식";
WriteLine($"{n}, {s}");
int n = 123;
WriteLine("{0}", n>100?"큼":"작음");
int n = 123;
WriteLine($"{(n > 100 > "큼":작음")}");