덤
- 오늘 하던 딴짓: 플러터 튜토리얼
- 아니 수업중에 갑자기 비주얼 스튜디오가 멋대로 업데이트를 하잖아 그래서 vscode에 빠르게 C# 실행 환경 구축함 되긴 되더라
개요
- 윈도우는 프로그램 확장자가 exe이고, 명령이 숫자로 표현되어 CPU가 그걸 수행한다. CPU가 이해할 수 있는 언어는 기계어.
- 요즘에는 기계어부터 최상위 언어까지 이해하는 사람을 원한다 아니 그게 신입한테 기대할 일이냐고요 그런 사람이 많을 수는 있어 인정하는데 그 사람들이 경력이 몇년인데요
- 인간이 쓰기 위한 프로그래밍 언어가 있다. 영어로 표현된다. 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
static Main() : 프로그램의 진입점. 프로그램이 실행될 때 가장 먼저 호출되는 메서드입니다.
1 2 3 4 5
class Program { public static void Main() { System.Console.WriteLine("hello, C#"); } }
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.SomeClass를MyCompany.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()를 사용하여 문자열을 숫자로 변환하는 과정을 거쳐야 한다.
- 사용자로부터 숫자 입력을 받는 방법
- Console.ReadLine() 메서드의 반환값은 string 타입이다.
- 입력받은 문자열을 숫자로 변환하는 방법
- 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 예: 파이썬
- 프로그래밍 언어에서의 변수의 개념 구분
- boxed variable: 변수에 저장된 값이 실제로는 객체의 참조값인 경우 (ex: string, class). C/C++, 자바, C#의 일반적인 변수. 선언 시 메모리 크기가 정해지며 초과하면 에러가 발생하거나 overflow 발생
- 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 method : 클래스에 소속된 메소드. 객체와 관련된 기능이 아닌, 클래스와 관련된 기능을 수행하는 메소드.
- 프로퍼티의 유형
- static property : 클래스에 소속된 프로퍼티. 객체와 관련된 기능이 아닌, 클래스와 관련된 기능을 수행하는 프로퍼티.
- 타입.프로퍼티이름 으로 호출하는 프로퍼티. 특정 데이터와는 관련없고, 타입과 연관된 기능수행
- instance property : 객체에 소속된 프로퍼티. 객체와 관련된 기능을 수행하는 프로퍼티.
- “변수.프로퍼티이름” 으로 호출하는 프로퍼티. 객체가 보관중인 데이터와 관련된 기능 수행
- static 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 -> 비주얼 스튜디오 실행 시 콘솔 창 안 나옴