C# 프로그래밍 (1)
포스트
취소

C# 프로그래밍 (1)

개요

  • 윈도우는 프로그램 확장자가 exe이고, 명령이 숫자로 표현되어 CPU가 그걸 수행한다. CPU가 이해할 수 있는 언어는 기계어.
    • 요즘에는 기계어부터 최상위 언어까지 이해하는 사람을 원한다 아니 그게 신입한테 기대할 일이냐고요 그런 사람이 많을 수는 있어 인정하는데 그 사람들이 경력이 몇년인데요
  • 인간이 쓰기 위한 프로그래밍 언어가 있다. 영어로 표현된다. 2종류가 있음.
    1. 인터프리터: 한 줄 읽고 바로 실행. 예: 파이썬. 쉬운데 느리고 안정성이 떨어짐. 안정성이 떨어진다는 말은 일단 실행을 하면서 확인하기 때문에 뒷부분에 문제가 있어도 앞부분을 실행하다 말고 발견하기 때문이라는 말임.
    2. 컴파일: 전체 코드를 기계어로 바꾼 후 실행. 빠르고 안정적이지만 어려움. C/C++.
  • 컴파일 언어는 또 2가지로 나뉜다
    • 중간 언어를 만들기
      • 호환성이 좋고 하나의 코드로 다양한 환경에서 실행 가능, 메모리 관리는 가상머신이 알아서 해주고 안정성 증가
      • 자바 jvm 같은 거. 거의 모든 환경에서 사용 가능하나 아래 방식보다 약간 느림.
        • 자바는 자바를 배워야만 자바를 쓸 수 있고 jvm이 만들어진다.
        • C#은 자바랑 비슷하게 IL code → CLR(기계어)을 거쳐서 실행되지만 자바와 달리 C++도 동일한 방식으로 실행 가능하다(나름 차별점임). 그럼 언어를 그대로 쓰면 어떻게 실행 방식을 바꾸냐? 마소가 만든 컴파일러를 쓰면 됨. 이걸 공통 실행 환경이라 해서 CLR이라 하는 거임.
    • 바로 기계어를 만들기
      • C/C++, Rust 같은 거.
      • 빠르지만 플랫폼에 종속되고, 메모리 관리를 개발자가 직접 하기 때문에 그 점에서 위험성이 좀 있음.
  • 언어 활용
    • 파이썬: AI 개발에 많이 사용
    • 자바: 웹에 많이 씀
    • C#: 유니티, UI(네비게이션, 관리 프로그램 등) 개발에 많이 씀

C# 기초

  • C# 언어
  • 확장자: .cs
  • 파일 포맷: UTF-8(권장)
  • 소스 스타일: PascalCase(권장), C/C++과 유사. 세미콜론 필요.

  • entry point
    1. static Main() : 프로그램의 진입점. 프로그램이 실행될 때 가장 먼저 호출되는 메서드입니다.

      1
      2
      3
      4
      5
      
       class Program {
           public static void Main() {
               System.Console.WriteLine("hello, C#");
           }
       }
      
    2. top-level 프로그래밍 방식: 파이썬과 동일. C# 9.0부터 도입된 기능으로, Main() 메서드 없이도 프로그램을 작성할 수 있습니다. 컴파일러가 자동으로 Main() 메서드를 생성하여 실행합니다.

      1
      
       System.Console.WriteLine("hello, C#");
      
    • 간단한 코드를 쓸 때는 굳이 명시적 진입점을 안써도 되긴 하는데, 코드가 길어지면 진입점이 따로 있는 게 낫다.
      • 진입점이 따로 있으면, 프로그램의 시작 지점을 명확히 알 수 있고, 코드의 구조가 더 명확해집니다. 또한, 진입점이 있으면 프로그램의 흐름을 제어하기가 더 쉬워집니다. 라고 코파일럿이 설명 덧붙여줌.
1
2
3
4
5
using System;
using static System.Console;

Write("Hello, ");
WriteLine("C#");
  • System: C#의 기본 네임스페이스 중 하나로, 다양한 기본 기능과 클래스를 포함하고 있습니다. 예를 들어, Console 클래스는 System 네임스페이스에 포함되어 있습니다.
  • Console: 콘솔 입출력을 위한 클래스입니다.
    • Console.WriteLine() 메서드는 콘솔에 문자열을 출력하고 줄 바꿈을 추가합니다.
    • Console.Write() 메서드는 줄 바꿈 없이 문자열을 출력합니다.
  • using: 네임스페이스를 코드에서 사용할 때, 해당 네임스페이스를 명시적으로 지정하지 않고도 사용할 수 있도록 하는 지시문입니다.
    • 예를 들어, using System;을 사용하면 Console.WriteLine()을 System.Console.WriteLine() 대신에 사용할 수 있습니다.
  • using static: 특정 클래스의 정적 멤버를 사용할 때, 해당 클래스 이름을 생략할 수 있도록 하는 지시문입니다.
    • 예를 들어, using static System.Console;을 사용하면 WriteLine()과 Write()를 Console.WriteLine()과 Console.Write() 대신에 사용할 수 있습니다.
  • using alias: 네임스페이스나 클래스에 별칭을 지정하여 코드에서 더 짧게 사용할 수 있도록 하는 지시문입니다.
    • 예를 들어, using Project = MyCompany.Project;을 사용하면 Project.SomeClassMyCompany.Project.SomeClass 대신에 사용할 수 있습니다.
1
2
3
4
5
// in codeA.cs
global using static System.Console;

// Write("Hello, ");
// WriteLine("C#");
1
2
3
// in codeB.cs
Write("Hello, ");
WriteLine("C#");
  • using의 위치: using 지시문은 일반적으로 파일의 맨 위에 위치합니다. 이는 코드의 가독성을 높이고, 해당 파일에서 어떤 네임스페이스와 클래스를 사용할 것인지 명확하게 보여줍니다.
  • global using: C# 10부터 도입된 기능으로, 특정 네임스페이스나 클래스를 프로젝트 전체에서 사용할 수 있도록 하는 지시문입니다. global using을 사용하면 해당 네임스페이스나 클래스를 모든 파일에서 명시적으로 지정하지 않고도 사용할 수 있습니다.
    • 예를 들어, global using System;을 사용하면 모든 파일에서 System 네임스페이스의 클래스와 멤버를 사용할 수 있습니다.
    • 반드시 global using은 파일의 맨 위에 위치해야 하며, 다른 using 지시문보다 먼저 작성되어야 합니다.
1
2
Console.Write("Hello, ");
Console.WriteLine("C#");
  • 기본적인 global using의 위치: {projectname}/obj/Debug/net10.0/{projectname}.GlobalUsings.g.cs
    • .NET 10.0 프로젝트에서는 기본적으로 System, System.Collections.Generic, System.IO, System.Linq, System.Net.Http, System.Threading, System.Threading.Tasks 네임스페이스가 global using으로 선언되어 있습니다.
    • 따라서, 이러한 네임스페이스의 클래스와 멤버는 프로젝트 내의 모든 파일에서 명시적으로 using 지시문을 작성하지 않고도 사용할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
string name;

Console.Write("input your name >> ");
name = Console.ReadLine();
Console.WriteLine("Hello, " + name + "!");

// 출력 확인을 위해 3초 대기
System.Threading.Thread.Sleep(3000);

Console.Clear(); // 콘솔 화면을 지웁니다.
Console.WriteLine("Welcome to C# programming!");
  • Console 클래스: 콘솔 입출력과 관련된 기능을 제공하는 클래스입니다.
  • Console.ReadLine(): 콘솔에서 한 줄의 입력을 읽어오는 메서드입니다. 사용자가 입력한 문자열을 반환합니다.
  • Console.Write(): 콘솔에 문자열을 출력하는 메서드입니다. 줄 바꿈 없이 출력합니다.
  • Console.WriteLine(): 콘솔에 문자열을 출력하는 메서드입니다. 출력 후 줄 바꿈을 추가합니다.
  • System.Threading.Thread.Sleep(): 지정된 시간(밀리초) 동안 현재 스레드를 일시 중지하는 메서드입니다. 예를 들어, Sleep(3000)은 3초 동안 스레드를 일시 중지합니다.
  • Console.Clear(): 콘솔 화면을 지우는 메서드입니다. 호출하면 콘솔에 출력된 모든 내용이 삭제되고, 커서가 화면의 왼쪽 상단으로 이동합니다.
1
2
3
4
5
6
7
8
9
string s;
int num;

Console.Write("input your number >> ");

s = Console.ReadLine(); // "10"
num = Convert.ToInt32(s); // "10" -> 10

Console.WriteLine($"Your number is {num}, and its square is {num * num}.");
  • C 언어의 scanf(): 입력과 변환을 동시에 수행하도록 함수가 지원함
  • C#에서는 입력과 변환을 별도의 단계로 수행해야 한다. 따라서, 먼저 Console.ReadLine()으로 문자열을 입력받고, 그 다음에 int.Parse()나 double.Parse()를 사용하여 문자열을 숫자로 변환하는 과정을 거쳐야 한다.
  • 사용자로부터 숫자 입력을 받는 방법
    1. Console.ReadLine() 메서드의 반환값은 string 타입이다.
    2. 입력받은 문자열을 숫자로 변환하는 방법
      • int.Parse(string s) : 문자열 s를 int 타입으로 변환한다.
      • Convert.ToInt32(string s) : 문자열 s를 int 타입으로 변환한다.
      • double.Parse(string s) : 문자열 s를 double 타입으로 변환한다.
      • Convert.ToDouble(string s) : 문자열 s를 double 타입으로 변환한다.
  • 사용자가 숫자를 입력하지 않으면 변환 불가
    • int.Parse()나 double.Parse()는 입력된 문자열이 숫자로 변환할 수 없는 경우 FormatException 예외를 발생시킨다.
    • Convert.ToInt32()나 Convert.ToDouble()는 입력된 문자열이 null인 경우 0을 반환하지만, 숫자로 변환할 수 없는 경우 FormatException 예외를 발생시킨다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// #1. Data type
int n = 0;
double d = 3.4;
char c = 'A';
string s = "hello";

// #2. var
var v1 = 10;
var v2 = 3.4;
var v3 = "hello";

// #3. literal
int a1 = 10;
int a2 = 0x10;  // 16진수 리터럴, 0x10은 16을 의미
int a3 = 0b10;  // 2진수 리터럴, 0b10은 2를 의미

int a4 = 1000000;
int a5 = 1_000_000;
  • 대부분 언어에서 변수에는 다 타입이 정해져 있다
    • C#에서는 변수의 타입을 명시적으로 선언하거나, var 키워드를 사용하여 컴파일러가 타입을 추론하도록 할 수 있다
    • 선언된 변수의 타입은 도중에 바꿀 수 없다 → static type check language ⇔ dynamic type check language 예: 파이썬
  • 프로그래밍 언어에서의 변수의 개념 구분
    1. boxed variable: 변수에 저장된 값이 실제로는 객체의 참조값인 경우 (ex: string, class). C/C++, 자바, C#의 일반적인 변수. 선언 시 메모리 크기가 정해지며 초과하면 에러가 발생하거나 overflow 발생
    2. postition variable: 변수에 저장된 값이 실제로는 객체의 참조값이 아닌 경우 (ex: int, double, char). 파이썬의 모든 변수, C#, 자바의 참조형 변수
  • 변수의 종류
    • short: 16비트 정수형, -32,768 ~ 32,767
    • ushort: 16비트 부호 없는 정수형, 0 ~ 65,535
    • int: 32비트 정수형, -2,147,483,648 ~ 2,147,483,647. 보통 권장됨.
    • uint: 32비트 부호 없는 정수형, 0 ~ 4,294,967,295
    • long: 64비트 정수형, -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
    • ulong: 64비트 부호 없는 정수형, 0 ~ 18,446,744,073,709,551,615
    • float: 32비트 부동소수점형, 약 ±1.5E-45 ~ ±3.4E38, 소수점 이하 7자리까지 정확
    • double: 64비트 부동소수점형, 약 ±5.0E-324 ~ ±1.7E308, 소수점 이하 15~16자리까지 정확. 보통 권장됨.
    • decimal: 128비트 고정소수점형, 약 ±1.0E-28 ~ ±7.9E28, 소수점 이하 28~29자리까지 정확, 금융 계산에 적합
    • bool: 논리형, true 또는 false 값 저장
    • char: 16비트 유니코드 문자형, 단일 문자 저장
    • string: 문자열형, 유니코드 문자들의 시퀀스 저장
  • var: 컴파일러가 변수의 타입을 추론하도록 하는 키워드. 선언과 동시에 초기화가 필요하며, 초기화된 값의 타입이 변수의 타입이 된다. var는 지역 변수에만 사용할 수 있다.
  • literal: 코드에 직접 작성된 값. 정수 리터럴, 실수 리터럴, 문자 리터럴, 문자열 리터럴 등이 있다. C#에서는 10진수, 16진수(0x), 2진수(0b) 형식의 정수 리터럴을 지원하며, 숫자 사이에 언더스코어(_)를 사용하여 가독성을 높일 수 있다.
1
2
3
4
5
6
7
8
9
10
11
using static System.Console;

// 핵심 : 초기화되지 않은 변수는 쓰기만 가능.
int n;
int a = 0;

a = n;  // error: 초기화되지 않은 변수는 읽을 수 없다.
WriteLine(n);

n = a;
a = n;
  • 변수는 초기화 후에 써야 한다. 초기화하지 않은 변수는 읽지 말고 쓰기만.
1
2
3
4
5
6
7
8
9
10
int n1;  // 초기화 안됨.

int n2 = 0;  // 보통 권장됨
int n3 = new int();  // 0 들어감

int n4 = default(int);  // int 타입의 기본값인 0이 들어감
int n5 = default;  // C# 7.1부터 지원, 타입 추론이 가능할 때 사용 가능

var v1 = default(int);  // int 타입의 기본값인 0이 들어감
var v2 = default;  // C# 7.1부터 지원, 타입 추론이 가능할 때만 사용 가능
  • 변수 초기화하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// #1. array 초기화
int[] x1 = { 1, 2, 3, 4, 5, 6};  // 보통 권장됨

int[] x2 = new int[]{ 1, 2, 3, 4, 5, 6};
int[] x3 = new []{ 1, 2, 3, 4, 5, 6};
var   x4 = new []{ 1, 2, 3, 4, 5, 6};
int[] x5 = [ 1, 2, 3, 4, 5, 6];  // C# 12.0

x1[0] = 0;

// #2. 다차원 배열
int[, ] x6 = {{1, 2}, {3, 4}, {4, 5}};

x6[0, 0] = 10;  // 파이썬/C++과의 인덱싱 표기 차이에 주의
  • 배열 선언하기
    • 배열은 같은 타입의 여러 값을 하나의 변수로 묶어서 관리할 수 있게 해주는 자료구조입니다.
    • 배열은 고정된 크기를 가지며, 인덱스를 사용하여 각 요소에 접근할 수 있습니다.
    • C#에서는 배열을 선언하고 초기화하는 다양한 방법이 있습니다.
    • 다차원 배열도 지원하여, 행렬과 같은 복잡한 데이터 구조를 표현할 수 있습니다.
  • 배열의 특징:
    • 배열은 참조 타입입니다. 즉, 배열 변수는 실제 데이터가 저장된 메모리 위치를 참조합니다.
    • 배열의 크기는 선언 시에 고정되며, 이후에는 변경할 수 없습니다.
    • 배열의 요소는 0부터 시작하는 인덱스를 사용하여 접근합니다.
1
2
3
4
5
using static System.Console;

// casting
double d = 3.4;
int n1 = (int)d;
  • 대입 시 자료형 차이에 주의
    • 작은 자료형에서 큰 자료형으로는 자동 형변환이 일어나지만, 큰 자료형에서 작은 자료형으로는 자동 형변환이 일어나지 않음
    • 큰 자료형에서 작은 자료형으로 변환하려면 명시적 형변환이 필요
  • 명시적 형변환 (explicit conversion)
    • 형변환 연산자 (cast operator) 사용
    • (자료형)값
1
2
3
4
5
6
7
8
9
using static System.Console;

// casting
double d = 3.1415926535897932384626433832795;
int n1 = (int)d;

WriteLine("d = {0}, n1 = {1}", d, n1);
WriteLine($"d = {d}, n1 = {n1}");
WriteLine($"d = {d:F2}, n1 = {n1}");
  • 출력 포맷팅
    • 나열해서 출력하기
      • WriteLine 메서드에서 문자열과 함께 콤마 ,로 구분된 값을 나열하면, 문자열의 중괄호 {} 안에 해당 값이 순서대로 삽입된다.
      • 예시: WriteLine(“Name: {0}, Age: {1}”, name, age) → name과 age 변수의 값을 문자열에 삽입한다.
    • 문자열 보간법 (string interpolation)
      • 문자열 앞에 $ 기호를 붙이고, 중괄호 {} 안에 변수나 표현식을 넣어서 문자열을 만들 수 있다.
      • 예시: $”Hello, {name}!” → name 변수의 값을 문자열에 삽입한다.
    • 서식 문자열 (format string)
      • 문자열 앞에 $ 기호를 붙이고, 중괄호 {} 안에 변수나 표현식과 함께 콜론 :을 사용하여 서식을 지정할 수 있다.
      • 예시: $”Pi is approximately {Math.PI:F2}” → Math.PI 값을 소수점 둘째 자리까지 표시한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;

int   n1 = 0;
System.Int32 n2 = 0;

Int32 n3 = 0;
// System.int   n4 = 0;

double d1 = 0;
Double d2 = 0;
System.Double d3 = 0;

string s1 = "A";
String s2 = "A";
System.String s3 = "A";

Console.WriteLine(typeof(int));  // System.Int32
Console.WriteLine(typeof(double));  // System.Double
  • CTS (Common Type System)
    • C#에서 사용하는 데이터 타입은 모두 CTS(Common Type System)라는 공통된 타입 시스템에 의해 관리됩니다.
    • CTS는 .NET Framework에서 사용되는 모든 데이터 타입을 정의하고 관리하는 시스템입니다.
    • CTS는 다양한 데이터 타입을 지원하며, C#에서 사용하는 기본 데이터 타입도 CTS에 포함됩니다.
    • CTS는 데이터 타입의 크기, 범위, 연산자 등을 정의하여 데이터 타입 간의 호환성을 보장합니다.
    • CTS는 C#에서 사용하는 데이터 타입을 모두 공통된 방식으로 관리하기 때문에, C#에서 사용하는 데이터 타입은 모두 CTS에 의해 관리됩니다.
  • 데이터 타입 표현
    • int, double 등: 사람이 쓰던 데이터 타입 표현
    • System.Int32, System.Double 등: .NET Framework에서 제공하는 데이터 타입 표현
    • Int32, Double 등: System 네임스페이스를 생략한 데이터 타입 표현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using static System.Console;

int score = 75;

if (score >= 90)
    WriteLine("A");
else if (score >= 80) {
    WriteLine("B");
}
else if (score >= 70) {
    WriteLine("C");
}
else if (score >= 60)
    WriteLine("D");
else
    WriteLine("F");
  • 조건문: 실행 흐름을 변경함
  • if
    • if (조건식) { … }
    • else if (조건식) { … }
    • else { … }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int num = 1;

switch (num) {
    case 1:
        Console.WriteLine("one");
        break;
    case 2:
        Console.WriteLine("two");
        break;
    case 3:
        Console.WriteLine("three");
        break;
    default:
        Console.WriteLine("other");
        break;
}

string weekday = DayOfWeek switch {
    DayOfWeek.Monday => "월요일",
    DayOfWeek.Tuesday => "화요일",
    DayOfWeek.Wednesday => "수요일",
    DayOfWeek.Thursday => "목요일",
    DayOfWeek.Friday => "금요일",
    DayOfWeek.Saturday => "토요일",
    DayOfWeek.Sunday => "일요일",
    _ => throw new ArgumentException("Invalid day of week")  // 생략 불가
};

Console.WriteLine($"오늘 {weekday}");
  • switch
    • switch (식) {…}
    • 중괄호 안에는 case n: … break;
    • if else로 호환 가능하지만, switch문이 더 깔끔한 경우가 있음
  • switch expression
    • 변수 초기화 시 switch 사용 가능
    • default 생략 불가(switch expression에서는 _로 표현)
    • 나름 최신 유행임
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using static System.Console;

int cnt = 0;
WriteLine("while loop:");
while (cnt < 5) {
    WriteLine(cnt);
    cnt++;
}

cnt = 0;
WriteLine("do-while loop:");
do {
    WriteLine(cnt);
    cnt++;
} while (cnt < 0);
  • while과 do-while
    • while은 조건식이 참인 동안 계속해서 반복하는 형태의 반복문입니다. 조건식이 처음부터 거짓이면 한 번도 실행되지 않을 수 있습니다.
    • do-while은 while과 달리, 조건식이 거짓이더라도 최소한 한 번은 실행되는 반복문입니다. do-while은 먼저 코드를 실행한 후에 조건식을 평가하기 때문에, 조건식이 처음부터 거짓이더라도 한 번은 실행됩니다.
1
2
3
4
5
6
string input;
do {
    Console.Write("입력 (종료하려면 Q): ");
    input = Console.ReadLine();
    Console.WriteLine(input);
} while (input != "Q");
  • 사용자가 Q를 입력할 때까지 무한히 echo하고, 최소 한 번은 입력받는 프로그램
  • 숙제: 야구 게임 만들어오기. 맞힐 때까지 못끝내. 1자릿수 게임과 n자릿수(중복 금지) 게임으로 각각 만들어오기.
1
2
3
4
5
6
7
using static System.Console;

int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

for (int i = 0; i < x.Length; i++) {
    WriteLine($"Index {i}: {x[i]}");
}
  • for문은 반복 횟수가 명확할 때 사용되는 반복문입니다. 초기화, 조건식, 증감식으로 구성되어 있으며, 반복 횟수를 쉽게 제어할 수 있습니다.
  • for문은 다음과 같은 구조를 가지고 있습니다: for (초기화; 조건식; 증감식) { … }
1
2
3
4
5
6
7
8
9
10
using static System.Console;

int n = 9;

for (int i = 0; i < n; i++) {
    for (int j = 0; j < n - i; j++) {
        Write("*");
    }
    WriteLine();
}
  • for 실습: 별 찍기
1
2
3
4
5
6
7
using static System.Console;

int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

foreach (var item in x) {  // var 권장: 요소 타입이 바뀌어도 코드 수정이 필요 없음
    WriteLine($"Item: {item}");
}
  • foreach: 컬렉션의 각 요소에 대해 반복적으로 작업을 수행하는 반복문입니다. 컬렉션의 요소를 순회하면서 각 요소에 대해 지정된 작업을 수행할 수 있습니다.
  • foreach문은 다음과 같은 구조를 가지고 있습니다: foreach (var item in collection) { … }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using static System.Console;

// 핵심
// => C# 의 모든 변수는
// 1. 데이터(값)을 저장하고
// 2. 데이터 관련 메소드(method, 함수)를 제공하고
// 3. 데이터 관련 속성(property) 를 제공한다.

// #1. 모든 변수는 데이터를 저장한다
int n = 10;
string s = "abcd";

// #2. 모든 변수는 자신이 저장한 데이터 관련 메소드(함수)를 제공한다.
string s2 = n.ToString(); // int형 변수 n이 가지고 있는 ToString() 메소드를 호출하여 n의 값을 문자열로 변환하여 s2에 저장한다.
bool b1 = s.Contains("a"); // string형 변수 s가 가지고 있는 Contains() 메소드를 호출하여 s가 "a"를 포함하는지를 알려주는 값을 b1에 저장한다.
string s3 = 25347896.ToString();  // 리터럴도 메소드 호출 가능

// #3. 모든 변수는 자신이 저장한 데이터 관련 속성(property) 제공한다.
WriteLine(s.Length); // string형 변수 s가 가지고 있는 Length 속성을 통해 s의 문자열 길이를 출력한다
WriteLine(s.Equals("abcd")); // string형 변수 s가 가지고 있는 Equals() 메소드를 호출하여 s가 "abcd"와 같은지를 알려주는 값을 출력한다
WriteLine(s.GetType()); // string형 변수 s가 가지고 있는 GetType() 메소드를 호출하여 s의 자료형을 알려주는 값을 출력한다
WriteLine(s.GetHashCode()); // string형 변수 s가 가지고 있는 GetHashCode() 메소드를 호출하여 s의 해시코드(정수값)를 알려주는 값을 출력한다
  • 자료형에 포함된 메소드들 (리터럴에도 사용 가능)
    • ToString() : 데이터를 문자열로 변환하는 메소드
    • GetType() : 데이터의 자료형을 알려주는 메소드
    • contains() : 문자열이 특정 문자열을 포함하는지를 알려주는 메소드
    • GetHashCode() : 데이터의 해시코드(정수값)를 알려주는 메소드
    • Equals() : 데이터가 같은지를 알려주는 메소드
  • 자료형에 포함된 속성들
    • Length : 문자열의 길이를 알려주는 속성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using static System.Console;

int num = 10;

string s = num.ToString(); // instance method
int ret = int.Max(10, 20); // static method

// property 도 2가지 종류
WriteLine(s.Length);    // s가 가진값("10") 의 길이
WriteLine(int.MaxValue);// int 타입이 가질수 있는 최대값
WriteLine(int.MinValue);// int 타입이 가질수 있는 최대값

// 다양한 타입 캐스팅
int n1 = Convert.ToInt32("123"); // Convert 클래스의 static 메소드 사용
int n2 = int.Parse("456");  // int 클래스의 static 메소드 사용
  • 메소드의 유형
    • static method : 클래스에 소속된 메소드. 객체와 관련된 기능이 아닌, 클래스와 관련된 기능을 수행하는 메소드.
      • 타입.메소드이름() 으로 호출하는 메소드. 특정 데이터와는 관련없고, 타입과 연관된 기능수행
    • instance method : 객체에 소속된 메소드. 객체와 관련된 기능을 수행하는 메소드.
      • “변수.메소드이름()” 으로 호출하는 메소드. 객체가 보관중인 데이터와 관련된 기능 수행
  • 프로퍼티의 유형
    • static property : 클래스에 소속된 프로퍼티. 객체와 관련된 기능이 아닌, 클래스와 관련된 기능을 수행하는 프로퍼티.
      • 타입.프로퍼티이름 으로 호출하는 프로퍼티. 특정 데이터와는 관련없고, 타입과 연관된 기능수행
    • instance property : 객체에 소속된 프로퍼티. 객체와 관련된 기능을 수행하는 프로퍼티.
      • “변수.프로퍼티이름” 으로 호출하는 프로퍼티. 객체가 보관중인 데이터와 관련된 기능 수행
1
2
3
4
using static System.Console;

WriteLine(Convert.ToDouble(ReadLine())); // Convert 클래스의 static 메소드 사용
// WriteLine(double.Parse(ReadLine()));  // double 클래스의 static 메소드 사용  // 보통 많이 씀
  • 사용자에게 double 값 한개를 입력받아서 화면 출력해 보세요
1
2
3
4
5
6
// 사각형의 면적을 구하는 함수
int GetRectArea(int x1, int y1, int x2, int y2) {
    return (x2 - x1) * (y2 - y1);
}

int area = GetRectArea(1, 1, 10, 10);
  • OOP1 : Object Oriented Programming 1
    • 아래 코드는 사각형의 면적을 구하는 함수.
    • 사각형이라는 데이터 타입이 없기 때문에 모든 속성을 파라미터로 전달하는 번거로움이 있음
    • 사각형이라는 데이터 타입을 만들어서 쓰는 게 객체지향이라는 거임
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Console.WriteLine(new Rect(1, 1, 10, 10).GetArea());

class Rect {
    // 필드 : 클래스의 속성
    public int left;
    public int top;
    public int right;
    public int bottom;

    // 생성자 : 클래스의 인스턴스를 생성할 때 호출되는 메소드
    public Rect(int left, int top, int right, int bottom) {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
    }

    // 메소드 : 클래스의 기능
    public int GetArea() {
        return (right - left) * (bottom - top);
    }
}
  • OOP2 : Object Oriented Programming 2
    • OOP1에서 사각형의 면적을 구하는 함수를 만들었음
    • 하지만 사각형이라는 데이터 타입이 없기 때문에 모든 속성을 파라미터로 전달하는 번거로움이 있었음
    • 사각형이라는 데이터 타입을 만들어서 쓰는 게 객체지향이라는 거임
  • 클래스 선언 양식: class 클래스명 { 필드; 생성자; 메소드; }
  • C#은 명시적 진입점이 없을 경우 실행부가 클래스 선언보다 먼저 나와야 한다(C++과 다름)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Rect {
    // 필드 : 클래스의 속성
    public int left;
    public int top;
    public int right;
    public int bottom;

    // 생성자 : 클래스의 인스턴스를 생성할 때 호출되는 메소드
    public Rect(int left, int top, int right, int bottom) {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
    }

    // 메소드 : 클래스의 기능
    public int GetArea() {
        return (right - left) * (bottom - top);
    }
}

public class Program {
    public static void Main() {
        Console.WriteLine($"rect area: {new Rect(1, 1, 10, 10).GetArea()}");
    }
}
  • 명시적 진입점을 포함한 클래스 작성
  • 이미 만들어진 클래스를 잘 쓸 줄 알면 된다
1
2
3
4
using System.Windows;

// MessageBox.Show("Hello, World!");
MessageBox.Show(messageBoxText: "안녕하세요", caption: "반갑습니다");
  • C#은 라이브러리가 참 많다
  • WPF: Windows Presentation Foundation
    • GUI 라이브러리
    • DirectX 기반
  • 다만 WPF를 사용하려면 프로젝트 자체를 WPF용으로 만들어야 함. 템플릿이 복잡해 초심자에게 권장되지 않음.
  • 프로젝트 설정 파일에서 WPF 관련 설정을 직접 추가하면 “콘솔 응용프로그램” 프로젝트에서도 사용 가능. 템플릿이 간결해 초심자에게 권장됨.
    • {projectname}.csproj 파일에서 아래의 2줄 수정 및 추가
    • <TargetFramework>net10.0-windows</TargetFramework> → 원래 있으니 수정
    • <UseWPF>true</UseWPF> → 새로 추가
1
2
3
4
5
6
7
8
9
10
using System.Windows;

class Program {
    [STAThread]  // WPF는 STAThread에서 실행되어야 한다
    public static void Main() {
        Window window = new Window();
        window.Show();
        // MessageBox.Show("Hello, WPF!");
    }
}
  • 직접 window를 만들어보겠다
  • WPF는 STAThread에서 실행되어야 한다
  • 아무것도 없이 말 그대로 창만 만들려면 생성하고 show 하면 된다.
    • 대신 실행하자마자 사라짐
  • MessageBox를 띄우면 창이 보이긴 하는데, MessageBox가 우선순위가 높아 창을 만질 수 없다.
1
2
3
4
5
6
7
8
9
10
11
12
using System.Windows;

class Program {
    [STAThread]
    public static void Main() {
        Window window = new Window();
        window.Show();

        Application app = new Application();
        app.Run();
    }
}
  • 사라지지 않고 만질 수 있는 창을 만들겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Program {
    [STAThread]
    public static void Main() {
        Window window = new Window();
        window.Show();

        window.Title = "WPF Window";
        window.Width = 400;
        window.Height = 300;
        window.Background = System.Windows.Media.Brushes.LightBlue;

        Application app = new Application();
        app.Run();
    }
}
  • 윈도우 커스텀하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Windows;

class Program {
    [STAThread]
    public static void Main() {
        Window window = new Window();
        window.Show();

        window.Title = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
        window.MouseLeftButtonDown += Window_MouseLeftButtonDown;
        window.MouseRightButtonDown += Window_MouseRightButtonDown;

        Application app = new Application();
        app.Run();
    }

    private static void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
        MessageBox.Show("마우스 왼쪽 버튼이 눌렸습니다.");
    }

    private static void Window_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
        MessageBox.Show("마우스 오른쪽 버튼이 눌렸습니다.");
    }
}
  • 윈도우에 마우스 이벤트 추가하기
  • {projectname}.csproj에 WinExe -> 비주얼 스튜디오 실행 시 콘솔 창 안 나옴
이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.

Python 프로그래밍 및 데이터 분석 실무 (10)

C# 프로그래밍 (2)