# Random 사용법
Random rand = new Random();
int choice = rand.Next(0, 3); // 0 ~ 2 랜덤 값 추출
# Convert.Toint32() 사용법
int choice = Convert.ToInt32(Console.ReadLine());
Convert.ToInt32() 메서드는 "아무거나 → int32"로 전환해 준다
"string → int"만 가능한 int.Parse() 보다 활용성이 높아서
int.Parse()를 사용하지 않고 Convert.ToInt32()만을 사용해도 된다
# 열거형
C++의 enum을 사용하는 경우에는 '::'를 통해 스페이스를 불러오는데
C#의 enum을 사용하는 경우에는 '.'을 통해 스페이스를 불러온다
그리고 C++과 마찬가지로 enum 자료형은 (int) 캐스팅변환은 필수이다
enum의 접근지정자를 작성하지 않으면,
클래스 외부에서 선언된 enum은 internal (같은 어셈블리에서만 접근 가능)
클래스 내부에서 선언된 enum은 private (클래스 내부에서만 사용 가능)이다
참고로, 같은 .exe 또는 같은 .dll처럼 하나의 동일 프로그램이
같은 어셈블리라는 의미이다
일반적으로 enum은 외부에서 사용해야 하는 경우가 대부분이고
중복된 enum 발생을 막으며 유지보수에도 도움 되기에 public이 정석이다
# 함수
C#은 객체지향(OOP) 중심인 언어이기 때문에
C++처럼 전역 변수와 전역 함수를 직접 사용할 수 없다
모든 변수와 함수는 반드시 클래스(class) 또는 구조체(struct) 내부에 포함되어야 한다
물론, static 키워드를 통해 전역 변수와 전역 함수인 것처럼 사용은 충분히 가능하다
# 복사 vs 참조(ref 키워드)
복사와 참조의 개념은 C++과 동일하지만
이를 구분하는 방법은 C#에서는 ref 키워드를 통해 구분한다
class A
{
static void FunctionByValue(int input) // 값으로 전달 (복사됨)
{ // 값으로 전달 (복사됨)
input = 10;
}
static void FunctionByRef(ref int input) // 참조로 전달 (원본 값 변경 가능)
{
input = 10;
}
}
class Program
{
static void Main()
{
int a = 0;
A.FunctionByValue(a); // 값 복사 (원본 `a`는 변경되지 않음)
Console.WriteLine(a); // 0 출력
A.FunctionByRef(ref a); // 참조 전달 (`a`의 원본 값이 변경됨)
Console.WriteLine(a); // 10 출력
}
}
# ref vs out
ref는 위에서 본 것처럼 참조키워드이다
out은 참조를 사용해 반환하는 키워드로
함수 내부에서 변수의 원본 값을 변경하는 경우 혹은 반환을 여러 개 하는 경우에 사용이 된다
키워드 | 함수 들어올 때 값 | 함수 끝날 때 값 | 의도 |
ref | 초기화되어 있어야 함 | 변경할 수도, 안 할 수도 있음 | 값을 넘겨주고 받을 수도 있음 |
out | 초기화 안 되어도 됨 | 반드시 함수 안에서 값 채워야 함 | "출력 전용" — 함수에서 값을 만들어서 넘김 |
좀 더 직관적으로 정리하면,
"참조한 원래 값 수정 or 안 수정" → ref
"새 값(들)을 뱉어줘야" → out
사용 예시는 아래와 같다
핵심은 out으로 여러 값들을 반환도 가능하고
핵심적인 값 하나는 반환타입으로 반환도 가능하다는 것이다
class A
{
static int Function(int input) // C++에서 자주 쓰는 일반적인 반환 방식
{
return input * 100;
}
static bool Function2(int input, out int output) // C#만 가능한 `out` 키워드 활용
{
if (input < 0)
{
output = 0; // 주의! `out` 변수는 값이 없는 상태에서 반환은 불가
return false;
}
output = input * 100; // `out`을 통해 값을 반환
return true;
}
}
class Program
{
static void Main()
{
int a = 5;
int value = A.Function(a); // 일반적인 반환
Console.WriteLine($"Function 결과: {value}");
int value2;
bool isSuccess = A.Function2(a, out value2); // `out`을 사용한 반환
Console.WriteLine($"Function2 성공 여부: {isSuccess}, 결과값: {value2}");
}
}
# Named Arguments
Optional Arguments를 함수 인자에서 활용해서 사용하는 경우에
C++은 기본 인자를 사용할 때 순서를 반드시 맞춰야 하는 제약이 있었다
반면, C#은 Named Arguments를 사용하면 원하는 매개변수만 지정 가능해서 매우 편리하다
// C++
// C++에서는 기본값을 지정할 수 있지만, 순서를 건너뛸 수 없음
int Add(int a, int b, int c = 0, float d = 1.0f, double e = 3.0)
{
return a + b + c;
}
int main()
{
std::cout << Add(1, 2, 2, 2.0f); // 순서대로만 채울 수 있음
// `Add(1, 2, d: 2.0f);` 이런 방식은 불가능!
}
// C#
static int Add(int a, int b, int c = 0, float d = 1.0f, double e = 3.0)
{
return a + b + c;
}
static void Main()
{
int result = Add(1, 2, d: 2.0f); // `d`만 변경 가능
}
'C# > [루키스] C#' 카테고리의 다른 글
[C# 섹션 5] 객체지향 - 데이터 영역과 생성자 (0) | 2025.06.20 |
---|---|
[C# 섹션 5] 객체지향 - 객체의 복사와 참조 (0) | 2025.06.20 |
[C# 섹션 2] 데이터 - 스트링포맷 (0) | 2025.06.19 |
[C# 섹션 2] 데이터 - 연산 (1) | 2025.06.18 |
[C# 섹션 2] 데이터 - 자료형 (1) | 2025.06.18 |