C#에서 대부분의 메서드는 메서드에 제공해야 하는 데이터를 정의하는 0개 이상의 매개 변수를 가질 수 있습니다. 메서드를 호출하는 모든 코드는 데이터(인수라고 함)를 메서드에 전달해야 합니다. 메소드는 입력을 매개변수로 선언하고 인수 형식으로 코드를 호출하여 제공됩니다.
예를 들어, 다음 메소드와 후속 메소드 호출을 고려하십시오.
static void Greet(string greeting){ Console.WriteLine(greeting); } ... Greet("Hello");
위의 예에서 Greeting은 Greet() 메서드의 매개변수이고 "Hello"는 메서드에 전달된 인수입니다.
메소드를 호출하고 인수를 전달하면 값으로 전달됩니다. 즉, 메소드에 전달될 때 값의 복사본이 생성됩니다. 메소드 내부의 인수에 대한 변경 사항은 원래 변수에 반영되지 않습니다.
using System; int number = 8; Increase(number); Console.WriteLine(number); // prints 8 static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 }
개체와 같은 참조 유형 변수를 전달할 때 C#은 여전히 참조를 복사합니다. 변수가 실제 객체가 아닌 참조를 보유하기 때문입니다. 따라서 참조 변수의 복사본이 전달되더라도 둘 다 메모리에서 동일한 개체를 참조합니다. 따라서 메서드 내부의 변수에 의해 개체에 적용된 모든 변경 사항은 메서드 외부의 변수에서 볼 수 있습니다.
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 }
그러나 메소드 내에서 변수 값 자체를 변경하면 실제 객체가 아닌 복사본만 변경되기 때문에 해당 변경사항이 메소드 외부에 반영되지 않습니다. 예를 들어 메서드 내에서 null에 인수를 할당할 수 있으며 실제 변수는 변경되지 않은 상태로 유지됩니다.
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 50000 static void Promote(User u){ u = null; }
C#은 메소드의 매개변수를 제어할 수 있는 세 가지 다른 수식어 키워드를 허용합니다.
참조 수정자
C#을 사용하면 ref를 사용하여 참조로 매개변수를 전달할 수 있습니다. 수정자. 전달되는 변수가 참조 유형 또는 값 유형에 속하는지 여부는 중요하지 않습니다. 매개변수와 인수는 모두 동일한 메모리 위치를 참조합니다.
다음 예에서 인수 u를 null로 설정하면 john 변수도 null이 되어 null 참조 예외가 발생합니다.
예
using System; var john = new User{ Name = "John", Salary = 50000 }; Promote(ref john); Console.WriteLine(john.Salary); // throws System.NullReferenceException static void Promote(ref User u){ u = null; }
ref 수정자와 함께 전달된 인수는 전달되기 전에 초기화되어야 합니다.
아웃 수정자
를 제외하고 ref 수정자와 유사합니다.
-
인수는 함수에 들어가기 전에 초기화할 필요가 없습니다.
-
인수는 함수에서 나오기 전에 초기화(할당)되어야 합니다.
아래 예에서 Hire 함수는 out 수정자를 통해 전달된 새 사용자 개체를 초기화합니다. 변수는 변수 john이 Hire 메서드를 호출할 때 즉석에서 선언됩니다.
using System; Hire(out User john); Console.WriteLine(john.Salary); // prints 50000 static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; }
참조 좋아요 수정자, out으로 표시된 변수 수정자는 참조로 전달됩니다.
종종 외부 변수는 다음과 같이 함수에서 여러 반환 값을 가져오는 데 사용됩니다. -
using System; var john = new User{ Name = "John", Salary = 50000 }; bool shouldPromote = Raise(john.Salary, out double hike); Console.WriteLine(shouldPromote); // True Console.WriteLine($"Hike Amount = {hike}"); // prints 5000 static bool Raise(int salary, out double hike){ hike = salary * 0.1; return hike < 7000; }
in 수정자
ref와 유사합니다. 그리고 밖 in을 허용하는 메서드를 제외하고 매개변수 인수의 값은 인수를 수정할 수 없습니다. 시도하면 C# 컴파일러가 컴파일 시간 오류를 생성합니다.
안에 매개변수는 컴파일러가 큰 값 유형의 메모리를 매개변수 변수로 복사하는 것과 동시에 개체가 우발적으로 수정되는 것을 방지합니다. 이것은 메소드에 큰 값 유형을 전달할 때 매우 유용합니다.
var point = new Coord(); Verify(point); static void Verify(in Coord c){ // error: Cannot assign to variable 'in Coord' because it is a readonly variable c = new Coord(); } struct Coord{ public int X; public int Y; }
예
using System; class Program{ static void Main(){ int number = 8; Increase(number); Console.WriteLine(number); // prints 8 var john = new User { Name = "John", Salary = 50000 }; Promote(john); Console.WriteLine(john.Salary); // prints 60000 Leave(john); Console.WriteLine(john.Salary); // prints 60000 LeaveByRef(ref john); Console.WriteLine(john?.Salary); // prints nothing User dave; Hire(out dave); Console.WriteLine(dave.Salary); // prints 50000 } static void Increase(int num){ num = num + 1; Console.WriteLine(num); // prints 9 } static void Promote(User u){ u.Salary += 10000; Console.WriteLine(u.Salary); // prints 60000 } static void Leave(User u){ u = null; } static void LeaveByRef(ref User u){ u = null; } static void Hire(out User u){ u = new User{ Name = "John", Salary = 50000 }; } } class User{ public string Name { get; set; } public int Salary { get; set; } }
출력
9 8 60000 60000 60000 50000