함수의 매개변수 순서와 무관하게 이름을 통해 호출하도록 하는 기능입니다.
코드 작성하다가 순서가 기억 안날 때 유용할 수 있습니다.
public static void Profile(int id, string name, string phone)
{
Console.WriteLine($"아이디는 {id}, 이름은 {name}, 전화번호는 {phone}");
}
public static void Main2()
{
// 함수 호출시 이름을 명명하고 순서와 상관없이 호출 가능
Profile(phone: "010-1111-2222", id: 1, name: "홍길동");
Profile(name: "홍길서", phone: "010-1234-5678", id: 2);
}
함수의 매개변수가 초기값을 갖고 있다면, 함수 호출시 생략 가능한 기능입니다.
public static void AddStudent(string name, string home = "서울", int age = 8) { }
public static void Main()
{
AddStudent("철수"); // AddStudent("철수", "서울", 8);
AddStudent("영희"); // AddStudent("영희", "서울", 8);
AddStudent("민준", "인천"); // AddStudent("민준", "인천", 8);
AddStudent("미영", age: 7); // AddStudent("미영", "서울", 7);
}
매개변수의 갯수가 정해지지 않은 경우, 매개변수의 갯수를 유동적으로 사용하는 방법입니다.
public static int Sum(params int[] values)
{
int sum = 0;
for (int i = 0; i < values.Length; i++)
{
sum += values[i];
}
return sum;
}
public static void Main()
{
int[] values = { 1, 2, 3, 4, 5 }; // 원래는 이렇게 사용
Sum(values);
Sum(1, 3, 5, 7, 9);
Sum(3, 5, 7);
Sum();
}
매개변수를 출력전용으로 설정합니다.
public static void Divide(int left, int right, out int quotient, out int remainder)
{
quotient = left / right;
remainder = left % right;
// 함수의 종료전까지 out 매개변수에 값이 할당 안되는 경우 오류
}
public static void Main()
{
int quotient; // 이렇게 미리 선언도 가능하지만
Divide(5, 3, out quotient, out int remainder); // 여기서 int 바로 선언도 가능하다.
Console.WriteLine($"{quotient}, {remainder}"); // output : 1, 2
}
매개변수를 입력전용으로 설정합니다.
그리고 함수의 처음부터 끝까지 동일한 값을 보장하게 됩니다.
public static int Plus(in int left, in int right)
{
// left = 20; // error : 입력전용 매개변수는 변경 불가
return left + right;
}
public static void Main6()
{
int result = Plus(1, 3);
Console.WriteLine($"{result}"); // output : 4
}
매개변수를 원본참조로 전달합니다.
매개변수가 값형식인 경우에도 함수를 통해 원본값을 변경하고 싶을 경우 사용합니다.
public static void Swap(ref int left, ref int right)
{
int temp = left;
left = right;
right = temp;
}
public static void Main7()
{
int left = 10;
int right = 20;
Swap(ref left, ref right);
Console.WriteLine($"{left}, {right}"); // output : 20, 10
}
클래스 내부 필드를 외부에 공개하고자 할 때 사용을 합니다.
즉, 외부에서의 직접적인 접근을 제한하면서 내부적으로 기능은 숨긴 상황이지만
필요한 정보를 제공하거나 수정할 수 있게 만들어줍니다.
기본적으로 get과 set으로 구성되어 있는데 그렇다면 get, set은 무슨 역할을 할까요?
⭐ Get: 속성의 값을 읽을 때 호출해주는 기능으로 객체의 속성 값을 외부로 반환하는 역할입니다.
⭐ Set: 속성의 값을 쓸 때 호출해주는 기능으로 외부에서 속성 값을 변경할 때 사용됩니다.
public class Property
{
private int _number; // private로 설정되어 기본적으로 접근불가
public int Number
{
// Get -> _number 호출
get { return _number; }
// Set -> 값이 0 이상인지 확인하고 설정합니다.
set
{
if (value >= 0)
{
_number = value;
}
else
{
Console.Writeline("0보다 작습니다")
}
}
}
}
상당히 많이 사용해서 C#에서는 Get, Set 함수를 간소화해서 표현할 수 있게 기능을 지원합니다.
class 클래스명
{
public [반환형식] 속성이름 {get; set;}
}
public class Car
{
private string name;
public string Name { get { return name; } set { name = value; } }
public string Color { get; set; }
}
public static void Main()
{
Car car1 = new Car();
car1.Name = "모닝";
car1.Color = "검정";
Console.WriteLine($"차의 이름은 {car1.Name}이고 색상은 {car1.Color}이다.");
}
차의 이름은 모닝이고 색상은 검정이다.
public int num1 { get; } // get만 사용가능
public int num2 { get; private set; } // 속성의 접근제한자를 통한 캡슐화
public int num3 { get; } = 10; // 읽기전용 속성(상수처럼 사용가능)
public int num4 => GetHP(); // 읽기전용 속성(람다처럼 사용가능)
partial은 클래스, 구조체, 인터페이스를 분할하여 구현할 수 있도록 하는 기능입니다.
클래스의 여러가지 메서드를 동일한 클래스에 나누어서 사용하기 때문에
프로젝트 작업할 때 작업을 분산해서 하기 좋습니다!
// 전투담당자 Player 소스
public partial class Player
{
private int hp;
public void Attack() { }
public void Defense() { }
}
// 아이템담당자 Player 소스
public partial class Player
{
private int weight;
public void GetItem() { }
public void UseItem() { }
}
public partial class Login
{
public string ID { get; set; }
public string Password { get; set; }
}
public partial class Login
{
public void IdInput() => Console.WriteLine($"당신의 아이디는 {ID}");
public void PasswordInput() => Console.WriteLine($"당신의 비밀번호는 {Password}");
}
public static void Main()
{
Login login = new Login();
login.ID = "홍길동";
login.Password = "123456";
login.IdInput();
login.PasswordInput();
}
}
당신의 아이디는 홍길동
당신의 비밀번호는 123456
삼항 연산자는 조건문의 간단버전이라고 생각하면 되는데 정확히는 참, 거짓을 구분하는 연산자입니다.
int A = B ? true : false
A는 bool 변수, B는 조건식, B의 조건이 맞으면 true 출력 아니면 false 출력입니다.
public static void Main()
{
int left = 10;
int right = 20;
int bigger;
if (left > right)
{
bigger = left;
}
else
{
bigger = right;
}
위에 if문을 삼항연산자로 나타내면 한줄로 표현이 가능합니다.
int bigger = left > right ? left : right;
기본연산자의 연산을 함수로 재정의하여 기능을 구현하는 연산자 재정의라고 합니다.
public struct Point
{
public int x;
public int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
Point pos1 = new Point() { x = 3, y = 2 };
Point pos2 = new Point() { x = 4, y = 5 };
Point sumpos = pos1 + pos2; // 지원하지 않아 에러 발생
기본연산자를 호환하지 않는 사용자정의 자료형에 기본연산자 사용을 구현할 수 있습니다.
public struct Point
{
public int x;
public int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public static Point operator +(Point left, Point right)
{
int x = left.x + right.x;
int y = left.y + right.y;
return new Point() {x = x, y = y};
// 위에 3줄을 한 줄로 간단히 나타낼 수도 있다
// return new Point(left.x + right.x, left.y + right.y);
}
public static void Main()
{
Point pos1 = new Point() { x = 3, y = 2 };
Point pos2 = new Point() { x = 4, y = 5 };
Point sumpos = pos1 + pos2;
// 위에 코드를 밑에처럼 간단히 나타낼 수도 있다
// Point point = new Point(3, 2) + new Point(4, 5);
}