객체가 아닌 클래스 자체에 소속되어, 프로그램 전체에서 유일한 필드/메소드로 지정함.
인스턴스에서 static 필드/메소드에 접근은 불가능
class Person
{
static public string Name;
static public int Age;
public void printInfo()
{
Console.WriteLine($"Name:{Name} / Age:{Age}");
}
static public int returnAge()
{
return Age;
}
}
class Program {
static void Main(string[] args) {
Person wonjin = new Person();
Person someone = new Person();
Console.WriteLine(Person.returnAge()); // 0
Person.Name = "asdfasdf";
Person.Age = 53;
wonjin.printInfo(); // Name:asdfasdf / Age:53
someone.printInfo(); // Name:asdfasdf / Age:53
Console.WriteLine(Person.returnAge()); // 53
}
}
아래 코드는 매개변수로 값을 전달하고, 객체 내 메소드에서는 이 값을 위한 별도 메모리 공간을 할당함.
class IAMCLASS
{
public void swap (int a, int b)
{
int tmp = a;
a = b;
b = tmp;
Console.WriteLine($"IAMCLASS a:{a} , b:{b}");
}
}
class Program {
static void Main(string[] args) {
IAMCLASS one = new IAMCLASS();
int a = 5;
int b = 3;
one.swap(a, b);
Console.WriteLine($"Program a:{a} , b:{b}");
}
}
/*
IAMCLASS a:3 , b:5
Program a:5 , b:3
*/
ref 키워드를 붙여 참조를 전달하도록 설정할 수 있음
아래 코드는 메소드를 호출할 때 넘길 매개변수를 참조로 전달.
class IAMCLASS
{
public void swap (ref int a, ref int b)
{
int tmp = a;
a = b;
b = tmp;
Console.WriteLine($"IAMCLASS a:{a} , b:{b}");
}
}
class Program {
static void Main(string[] args) {
IAMCLASS one = new IAMCLASS();
int a = 5;
int b = 3;
one.swap(ref a, ref b);
Console.WriteLine($"Program a:{a} , b:{b}");
}
}
/*
IAMCLASS a:3 , b:5
Program a:3 , b:5
*/
함수 리턴자료형 앞, 리턴하는 변수(값) 앞에 ref키워드를 붙이면
---> 함수는 참조를 반환
반환받는 변수 앞에 ref키워드를 붙이면
---> 반환값을 참조로 받음
만약, 반환받는 변수 앞에 ref키워드가 없다면
---> 함수가 참조를 반환했더라도, 반환값을 값으로 받음.
class IAMCLASS
{
public string name = "wonjin";
public ref string returnName()
{
return ref name;
}
}
class Program {
static void Main(string[] args) {
IAMCLASS a = new IAMCLASS();
IAMCLASS b = new IAMCLASS();
Console.WriteLine(a.name); // wonjin
ref string a_str = ref a.returnName();
a_str = "aaaaaaaaaaaaaa";
Console.WriteLine(a.name); // aaaaaaaaaaaaaa
Console.WriteLine(b.name); // wonjin
string b_str = b.returnName();
b_str = "bbbbbbbbbbbbbbbbbbbbbbbbbbb";
Console.WriteLine(b.name); // wonjin
}
}
메소드 선언부, 호출부에 out키워드를 사용하면, 수행 결과 값을 호출자에게 전달.
메소드가 종료되기 전 out 키워드가 붙은 변수에 값을 할당해야 한다.
하지 않으면 컴파일 에러가 발생한다.
같은 기능을 ref를 사용하여 구현할 수도 있다. 그러나 out키워드를 사용하면 컴파일에러를 통해 개발자의 실수를 방지하는 이점이 있다.
class Program {
static void Divide(int a, int b, out int mok, out int rest)
{
mok = a / b;
rest = a % b;
}
static void Main(string[] args) {
int a = 53;
int b = 5;
Divide(a, b, out int c, out int d);
Console.WriteLine($"a/b={c} ,a%b={d}"); // a/b=10 ,a%b=3
}
}
같은 이름의, 매개변수갯수, 자료형이 다른 여러개의 메소드를 한 클래스 안에 구현할 수 있음.
컴파일시에 어떤 메소드를 호출하는 것인지 체크함 (오버로딩 수에 따른 성능영향 없음)
메소드 관리에 이점있음.
class a
{
public int add(int a, int b)
{
return a + b;
}
public string add(string a, string b)
{
return a + b;
}
}
class Program {
static void Main(string[] args) {
a aaa = new a();
Console.WriteLine(aaa.add(5, 3)); //8
Console.WriteLine(aaa.add("5353", "53")); // "535353"
}
}
class Program {
static int add(params int[] args)
{
int sum = 0;
foreach (int arg in args)
{
sum += arg;
}
return sum;
}
static void Main(string[] args) {
Console.WriteLine(add(5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3)); // 64
}
}
class Program {
static int add(int a, int b)
{
return a + b;
}
static void Main(string[] args) {
Console.WriteLine(add(5, 3)); // 8
Console.WriteLine(add(5, b: 3)); // 8
Console.WriteLine(add(a: 5, 3)); // 8
Console.WriteLine(add(a: 5, b: 3)); // 8
Console.WriteLine(add(b: 3, a: 5)); // 8
}
}
기본값을 갖는 매개변수는 호출시 생략할 수 있음.
기본값을 갖는 매개변수는 필수변수 뒤에 기재해야함.
static int add(int a, int b, int c=1000, int d=100000)
{
return a + b + c + d;
}
static void Main(string[] args) {
Console.WriteLine(add(a:5, b:3)); // 5 3 1000 100000 = 101008
Console.WriteLine(add(a: 5, b: 3, c: 53)); // 5 3 53 100000 = 100061
Console.WriteLine(add(a: 5, b: 3, c: 53, d:5353)); // 5 3 53 5353 = 5414
}
함수안의 함수.
로컬함수는 자신이 속한 메소드의 지역변수를 사용할 수 있음.
static int outer()
{
int a = 53;
int inner()
{
return a * a;
}
a = inner();
return a;
}
static void Main(string[] args) {
Console.WriteLine(outer());
Console.WriteLine(outer());
}