반응형

매개변수

 

params 키워드 - C# 참조

params(C# 참조)params (C# Reference) 이 문서의 내용 --> params 키워드를 사용하면 가변 개수의 인수를 사용하는 메서드 매개 변수를 지정할 수 있습니다.By using the params keyword, you can specify a method parameter that takes a variable number of arguments. 매개 변수 선언이나 지정된 형식의 인수 배열에 지정된 형식의 쉼표로 구분된 인수 목

docs.microsoft.com

더보기

params 키워드를 사용하면 가변 개수의 인수를 사용하는 메서드 매개 변수를 지정할 수 있습니다.

매개 변수 선언이나 지정된 형식의 인수 배열에 지정된 형식의 쉼표로 구분된 인수 목록을 보낼 수 있습니다. 인수를 보내지 않을 수도 있습니다. 인수를 보내지 않는 경우 params 목록의 길이는 0입니다.

메서드 선언에서 params 키워드 뒤에는 추가 매개 변수가 허용되지 않으며, params 키워드 하나만 메서드 선언에 사용할 수 있습니다.

params 매개 변수의 선언된 형식은 다음 예제와 같이 1차원 배열이어야 합니다. 그렇지 않으면 컴파일러 오류 CS0225가 발생합니다.

예제

다음 예제에서는 params 매개 변수에 인수를 보낼 수 있는 다양한 방법을 보여 줍니다.

C#복사

 

public class MyClass { public static void UseParams(params int[] list) { for (int i = 0; i < list.Length; i++) { Console.Write(list[i] + " "); } Console.WriteLine(); } public static void UseParams2(params object[] list) { for (int i = 0; i < list.Length; i++) { Console.Write(list[i] + " "); } Console.WriteLine(); } static void Main() { // You can send a comma-separated list of arguments of the // specified type. UseParams(1, 2, 3, 4); UseParams2(1, 'a', "test"); // A params parameter accepts zero or more arguments. // The following calling statement displays only a blank line. UseParams2(); // An array argument can be passed, as long as the array // type matches the parameter type of the method being called. int[] myIntArray = { 5, 6, 7, 8, 9 }; UseParams(myIntArray); object[] myObjArray = { 2, 'b', "test", "again" }; UseParams2(myObjArray); // The following call causes a compiler error because the object // array cannot be converted into an integer array. //UseParams(myObjArray); // The following call does not cause an error, but the entire // integer array becomes the first element of the params array. UseParams2(myIntArray); } } /* Output: 1 2 3 4 1 a test 5 6 7 8 9 2 b test again System.Int32[] */

 

 

디폴트 매개변수 주의사항

l  어떤 매개변수에 기본값을 지정하면 뒤쪽 파라미터도 전부 기본값을 해야한다.

l  기본값들은 컴파일 시점에 모두 알 수 있는 상수 값이어야 한다.

l  매개변수의 이름을 직접 지정 임의로 변경하지 X

l  기본값 변경 X

l  Ref, out 는 기본값 지정 X – 의미 있는 기본값 전달 안 됨

l  Var 타입 변수 사용 X

+ var dynamic의 차이점
전자는 문법적인 단축 방법일 뿐, 컴파일러가 실제 타입을 유추하도록 명령하는 것
후자는 지역 변수, 필드, 매개변수 사용 가능, 이미 완성된(컴파일 후) 인스턴스에 활용.

Ref out의 차이

둘은 CLR, IL 상에서 같은 역할을 한다. , ref를 문법적으로 맞는지 검사를 한다.
초기화되지 않은 변수를 전달하려고 하면 오류가 난다.

 

Params 키워드

가변 매개변수 전달의 경우 사용
params Object[] objects
식으로 사용하면 기정 거의 모든 타입을 매개변수로 받을 수 있다.

, 가변으로 하게 되도 결국 추가적인 성능저하를 초래한다. 매개변수가 많이 할당되는 만큼 힙에 할당하는 것이다.

 

상수화

C++ 은 변수들에 상수화를 지원하지만 C#에서는 그렇지 못하다. 이유는 CLR이 지원하지 않기 때문.

CLR이 상수화를 허용한다면 매 객체에 대해 쓰기 작업이 발생했는지 확인해야만 하며, 이로 인해 개발자들에게는 복잡성, 성능에는 치명적인 저하가 발생할 것이기 때문이다.

 

프로퍼티

 

속성 - C# 프로그래밍 가이드

속성(C# 프로그래밍 가이드)Properties (C# Programming Guide) 이 문서의 내용 --> 속성은 전용 필드의 값을 읽거나 쓰거나 계산하는 유연한 메커니즘을 제공하는 멤버입니다.A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. 공용 데이터 멤버인 것처럼 속성을 사용할 수 있지만,

docs.microsoft.com

더보기

속성은 전용 필드의 값을 읽거나 쓰거나 계산하는 유연한 메커니즘을 제공하는 멤버입니다. 공용 데이터 멤버인 것처럼 속성을 사용할 수 있지만, 실제로 접근자라는 특수 메서드입니다. 이렇게 하면 데이터에 쉽게 액세스할 수 있으며 메서드의 안전성과 유연성 수준을 올리는 데에도 도움이 됩니다.

속성 개요

  • 속성을 사용하면 클래스가 구현 또는 검증 코드를 숨기는 동시에 값을 가져오고 설정하는 방법을 공개적으로 노출할 수 있습니다.

  • get 속성 접근자는 속성 값을 반환하는 데 사용되고 set 속성 접근자는 새 값을 할당하는 데 사용됩니다. 이러한 접근자는 각기 다른 액세스 수준을 가질 수 있습니다. 자세한 내용은 접근자 액세스 가능성 제한을 참조하세요.

  • value 키워드는 set 접근자가 할당하는 값을 정의하는 데 사용됩니다.

  • 속성은 읽기/쓰기(get  set 접근자 모두 포함), 읽기 전용(get 접근자는 포함하지만 set 접근자는 포함 안 함) 또는 쓰기 전용(set 접근자는 포함하지만 get 접근자는 포함 안 함)일 수 있습니다. 쓰기 전용 속성은 거의 없으며 주로 중요한 데이터에 대한 액세스를 제한하는 데 사용됩니다.

  • 사용자 지정 접근자 코드가 필요 없는 단순한 속성은 식 본문 정의나 자동 구현 속성으로 구현할 수 있습니다.

지원 필드가 있는 속성

속성을 구현하는 한 가지 기본 패턴에는 private 지원 필드를 사용하여 속성 값을 설정 및 검색하는 작업이 포함됩니다. get 접근자는 private 필드의 값을 반환하고 set 접근자는 private 필드에 값을 할당하기 전에 데이터 유효성 검사를 수행할 수 있습니다. 또한 두 접근자 모두 데이터를 저장 또는 반환하기 전에 데이터에 대한 변환이나 계산을 수행할 수도 있습니다.

다음 예제에서 이 방법을 보여 줍니다. 이 예제에서 TimePeriod 클래스는 시간 간격을 나타냅니다. 내부적으로 이 클래스는 _seconds라는 private 필드에 시간 간격을 초 단위로 저장합니다. Hours라는 읽기/쓰기 속성을 사용하면 고객이 시간 간격을 시간 단위로 지정할 수 있습니다. get  set 접근자 모두 필요에 따라 시간 및 초 간의 변환을 수행합니다. 또한 set 접근자는 데이터의 유효성을 검사하고 시간(시)이 잘못된 경우 ArgumentOutOfRangeException을 throw합니다.

C#복사

 

using System; class TimePeriod { private double _seconds; public double Hours { get { return _seconds / 3600; } set { if (value < 0 || value > 24) throw new ArgumentOutOfRangeException( $"{nameof(value)} must be between 0 and 24."); _seconds = value * 3600; } } } class Program { static void Main() { TimePeriod t = new TimePeriod(); // The property assignment causes the 'set' accessor to be called. t.Hours = 24; // Retrieving the property causes the 'get' accessor to be called. Console.WriteLine($"Time in hours: {t.Hours}"); } } // The example displays the following output: // Time in hours: 24

식 본문 정의

속성 접근자는 식의 결과를 할당하거나 반환하기만 하는 한 줄로 된 문으로 구성되는 경우가 많습니다. 이러한 속성은 식 본문 멤버로 구현할 수 있습니다. 식 본문 정의는 => 기호와 속성에 할당하거나 속성에서 검색할 식으로 구성됩니다.

C# 6부터 읽기 전용 속성에서 get 접근자를 식 본문 멤버로 구현할 수 있습니다. 이 경우 get 접근자 키워드나 return 키워드를 모두 사용하지 않습니다. 다음 예제에서는 읽기 전용 Name 속성을 식 본문 멤버로 구현합니다.

C#복사

 

using System; public class Person { private string _firstName; private string _lastName; public Person(string first, string last) { _firstName = first; _lastName = last; } public string Name => $"{_firstName} {_lastName}"; } public class Example { public static void Main() { var person = new Person("Magnus", "Hedlund"); Console.WriteLine(person.Name); } } // The example displays the following output: // Magnus Hedlund

C# 7.0부터 get  set 접근자 모두를 식 본문 멤버로 구현할 수 있습니다. 이 경우 get  set 키워드가 있어야 합니다. 다음 예제에서는 두 접근자에 대해 식 본문 정의를 사용하는 방법을 보여 줍니다. return 키워드는 get 접근자와 함께 사용하지 않습니다.

C#복사

 

using System; public class SaleItem { string _name; decimal _cost; public SaleItem(string name, decimal cost) { _name = name; _cost = cost; } public string Name { get => _name; set => _name = value; } public decimal Price { get => _cost; set => _cost = value; } } class Program { static void Main(string[] args) { var item = new SaleItem("Shoes", 19.95m); Console.WriteLine($"{item.Name}: sells for {item.Price:C2}"); } } // The example displays output like the following: // Shoes: sells for $19.95

자동으로 구현된 속성

경우에 따라 get 속성과 set 접근자에서 지원 필드에 값을 할당하거나 지원 필드에서 값을 검색하기만 하고 추가 논리를 포함하지 않을 수 있습니다. 자동 구현 속성을 사용하면 코드를 간소화할 수 있을 뿐 아니라 C# 컴파일러에서 지원 필드를 투명하게 제공하도록 할 수 있습니다.

속성에 get  set 접근자가 모두 포함된 경우 두 접근자를 모두 자동 구현해야 합니다. 구현을 제공하지 않고 get  set 키워드를 사용하여 자동 구현 속성을 정의합니다. 다음 예제에서는 Name  Price가 자동 구현 속성인 점만 제외하고 이전 예제와 동일합니다. 이 예제에서는 매개 변수화된 생성자도 제거하므로 이제 SaleItem 개체가 매개 변수 없는 생성자 및 개체 이니셜라이저에 대한 호출을 통해 초기화됩니다.

C#복사

 

using System; public class SaleItem { public string Name { get; set; } public decimal Price { get; set; } } class Program { static void Main(string[] args) { var item = new SaleItem{ Name = "Shoes", Price = 19.95m }; Console.WriteLine($"{item.Name}: sells for {item.Price:C2}"); } } // The example displays output like the following: // Shoes: sells for $19.95

자동 구현 속성(Automatically Implemented Property, AIP)

프로퍼티를 정의하면서 get set 메서드의 구현부를 생략하면, C# 컴파일러는 자동으로 프로퍼티와 연결되는 private필드를 정의해준다.

단점

l  값을 초기화할 방법이 없다.

l  스트림에 serialize할 시 필드 이름에 의존하게 되는데, 타입을 serialize를 하면 매 컴파일 마다 이름이 바뀌게 되어 스트림으로 복원할 수 없게 된다.

l  중단점을 추가할 수 없다.

l  실행이 오래 걸리는 점 때문에 스레드 동기화에는 메서드를 사용해야 한다.

l  한 줄에서 여러 번 호출할 경우 프로퍼티는 매번 다른 값을 반환하지만, 필드는 같은 값을 반환한다.

l  객체 상태와는 무관하게 추가적인 메모리 요구, 다른 객체를 반환이 가능
필드는 항상 원천 객체 상태를 나타내는 참조를 반환

l  제네릭 사용 불가. 실은 개념적으로 맞지 않다. 객체의 상태와 무관하게 완전 독릭적인 행위를 하진 않는다.

반응형

'C# > CLR via' 카테고리의 다른 글

인터페이스  (0) 2020.03.25
이벤트 & 제네릭  (0) 2020.02.28
메서드  (0) 2020.02.19
참조 타입과 값 타입  (0) 2020.02.18
Object 그리고 캐스팅  (0) 2020.02.16
Posted by Lotus' Library
,