[C#] params 키워드를 사용하는 이유는 무엇입니까?

나는 이것이 기본적인 질문이라는 것을 알고 있지만 답을 찾을 수 없습니다.

왜 사용합니까? 함수 또는 함수를 사용하는 메소드를 작성하는 경우 코드를 제거해도 코드가없는 것처럼 100 % 완벽하게 작동합니다. 예 :

params로 :

static public int addTwoEach(params int[] args)
{
    int sum = 0;
    foreach (var item in args)
        sum += item + 2;
    return sum;
}

매개 변수없이 :

static public int addTwoEach(int[] args)
{
    int sum = 0;
    foreach (var item in args)
       sum += item + 2;
    return sum;
}



답변

다음과params 같이 메소드를 호출 할 수 있습니다.

addTwoEach(1, 2, 3, 4, 5);

없이는 params할 수 없습니다.

또한 두 경우 모두 배열을 매개 변수로 사용하여 메서드를 호출 할 수 있습니다 .

addTwoEach(new int[] { 1, 2, 3, 4, 5 });

params, 메서드를 호출 할 때 바로 가기를 사용할 수 있습니다.

관련이없는 방법을 크게 단축 할 수 있습니다.

public static int addTwoEach(params int[] args)
{
    return args.Sum() + 2 * args.Length;
}


답변

를 사용 params하면 인수없이 함수를 호출 할 수 있습니다. 없이 params:

static public int addTwoEach(int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

addtwoEach(); // throws an error

와 비교 params:

static public int addTwoEach(params int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

addtwoEach(); // returns 0

일반적으로 인수 수가 0에서 무한대까지 다양 할 수있는 경우 매개 변수를 사용하고 인수 수가 1에서 무한대까지 다양 할 경우 배열을 사용할 수 있습니다.


답변

통화에 원하는만큼 기본 유형 매개 변수를 추가 할 수 있습니다.

addTwoEach(10, 2, 4, 6)

반면 두 번째 형식에서는 배열을 매개 변수로 사용해야합니다

addTwoEach(new int[] {10,2,4,6})


답변

한 가지 위험 params키워드는 경우입니다 메서드를 호출하면, 코딩 된

  1. 누군가가 실수로 / 의도적으로 하나 / 더 제거 필요 메소드 서명에서 매개 변수를
  2. 서명 변경 직전의 파라미터 직전의 1 개 이상의 필수 파라미터가 params파라미터와 형식 호환이 가능한 params,

이러한 호출은 선택적 매개 변수로 취급되는 필수 매개 변수에 대해 이전에 의도 한 하나 이상의 표현식으로 계속 컴파일됩니다 params. 방금 최악의 경우가 발생했습니다. params매개 변수는 유형이었습니다.object[] 입니다.

개발자가 컴파일러가 손목을 때리는 데 필요한 모든 매개 변수가있는 메소드에서 매개 변수가 제거되는 훨씬 일반적인 시나리오 (예상되는 매개 변수 수가 변경되기 때문에)에 익숙하기 때문에 주목할 만합니다 .

저에게는 지름길 가치가 없습니다. (Type)[]without params는 재정의없이 0에서 무한대까지의 매개 변수로 작동합니다. 최악의 경우 , new (Type) [] {}적용되지 않는 통화에 통화 를 추가 해야합니다.

Btw, imho, 가장 안전하고 읽기 쉬운 방법은 다음과 같습니다.

  1. 명명 된 매개 변수를 통해 전달하십시오 ( VB; P에서 수십 년이 지난 후 C # ~ 20 년 에도 가능합니다 ).

    1.1. 매개 변수 순서, 호환 유형 및 / 또는 호출이 코딩 된 후 카운트 변경 후에 의도하지 않은 값이 매개 변수로 전달 되는 것을 방지 할 수 있는 유일한 방법입니다 .

    1.2. 그것은 감소 새로운 의미를 반영하는 것으로 새로운 식별자 이름 바로 옆 값에 전달되기 때문에, 파라미터 변화 후의 의미 그 가능성

    1.3. 쉼표를 계산하지 않고 Call to Signature에서 앞뒤로 건너 뛰어 어떤 매개 변수에 어떤식이 전달되는지 확인합니다.

    1.3.1. 그런데, 이런 이유로 혼자가해야 많은 (그냥하는 DRY 원칙의 잦은 오류가 발생하기 쉬운 위반을 방지 측면에서 읽을 코드도 언급하지 않기 수정 을)하지만,이 이유가 될 수 있습니다 기하 급수적으로 하나가있는 경우 더 중요 / 쉼표를 포함하는 더 많은 표현식 (예 : Multi-Dimensional Array Refs 또는 Multi-Parameter Function Calls) 이 경우 편집기에서 선택 항목의 모든 발생 항목 찾기 기능을 사용하여 (메서드 호출 매개 변수 마다 추가 단계를 계속 추가 할 수도 있음 ) 쉼표 계산을 자동화 할 수 없습니다.

    1.4. 선택적 매개 변수를 사용해야하는 경우 (선택적 params) 특정 선택적 매개 변수가 전달 된 통화를 검색 할 수 있습니다 (따라서 기본값이 아닐 수도 있고 최소한 기본값이 아닐 수도 있음).

(참고 : 이유 1.2. 및 1.3은 호출을 읽고 / 또는 변경해야 할 때 언급하지 않고 초기 호출을 코딩 할 때도 오류 가능성을 줄이고 줄일 수 있습니다.)

  1. 가독성을 높이기 위해 1 개의 PARAMETER-PER-LINE을 사용하십시오.

    2.1. 덜 어수선하고

    2.2. 그것은 좌우로 스크롤 할 필요가 없습니다 (그리고 대부분의 필사자는 여러 줄의 왼쪽 부분을 읽을 수 없으므로 오른쪽으로 스크롤하고 오른쪽 부분을 읽을 수 있기 때문에 PER-LINE을 수행해야 함).

    2.3. 전달 된 모든 매개 변수가 본질적으로 지정 문 (값 또는 참조를 로컬 변수에 지정)이기 때문에 지정 문에 대해 이미 발전시킨 “모범 사례”와 일치합니다. 코딩 스타일에서 최신 “Best Practice” 를 따르는 사람들이 한 줄에 여러 개의 Assignment Statements를 코딩하는 것을 꿈꾸지 않는 것처럼, “Best Practice” 내 “천재”를 따라 잡지 않아야합니다 . )는 매개 변수를 전달할 때 수행합니다.

참고 사항 :

  1. 이름이 매개 변수를 반영하는 변수를 전달하면 다음과 같은 경우 도움이되지 않습니다.

    1.1. 리터럴 상수를 전달하는 경우 (예 : ” ‘모범 사례'”조차도 명명 된 상수를 사용할 필요가없고 목적 이름을 메소드 이름에서 쉽게 추론 할 수없는 단순한 0/1, false / true 또는 null 임) ),

    1.2. 이 메소드는 호출자보다 훨씬 저수준 / 일반적이므로 변수의 이름을 매개 변수와 동일 / 유사하게 지정하지 않을 수 있습니다 (또는 그 반대).

    1.3. 유형 여전히 호환 가능하기 때문에 이전 통화가 여전히 컴파일 될 수있는 Signature의 매개 변수를 재정렬 / 교체 하고 있습니다.

  2. VS와 같은 자동 줄 바꿈 기능을 사용하면 위에서 언급 한 8 가지 이유 중 하나 (# 2.2) 만 제거됩니다. VS 2015 이전에는 자동 들여 쓰기 (!?! 실제로 MS?!?)하지 않았으므로 이유 # 2.1의 심각도가 증가합니다.

VS에는 명명 된 매개 변수 (한 줄에 하나씩; P)와 메서드 호출 스 니펫을 생성하는 옵션과 명명 된 매개 변수 ( VB의 Option Explicit와 개념 상 유사 함)와 비슷한 컴파일러 옵션이 있어야합니다. 똑같이 터무니 없지만 이제는 ”최고의 관행 ”에 필요합니다 .) 사실, “다시 Day “;), 1991 년에 커리어가 시작된 지 몇 달이 지났는데, 심지어 Named Parameters로 언어를 사용하기 (혹은 본 적이 있기도 전에) 나는 안티-셰이프를 가지고있었습니다. / 맹목적으로 “로스트의 끝을 자르십시오”라는 의미를 가진 사람을 보지 않고 그것을 (인라인 주석을 사용하여) 시뮬레이션하기에 충분하지 않습니다. 명명 된 매개 변수를 사용할 필요가 없습니다. 소스 코드 키 스트로크)는 대부분의 구문이 시작되었을 때 펀치 카드 시대의 유물입니다. 가독성이 많은 현대 하드웨어 및 IDE 및 훨씬 더 복잡한 소프트웨어의 경우에는 변명의 여지가 없습니다. 훨씬더 중요. “코드는 작성된 것보다 훨씬 자주 읽습니다”. 자동 업데이트되지 않은 코드를 복제하지 않는 한 누군가 (나 자신도) 나중에 읽으려고 할 때 저장된 모든 키 입력 비용이 기하 급수적으로 더 높아질 수 있습니다.


답변

과부하 방법을 만들 필요가 없으며 아래 표시된 것처럼 매개 변수가있는 단일 방법 하나만 사용하십시오.

// Call params method with one to four integer constant parameters.
//
int sum0 = addTwoEach();
int sum1 = addTwoEach(1);
int sum2 = addTwoEach(1, 2);
int sum3 = addTwoEach(3, 3, 3);
int sum4 = addTwoEach(2, 2, 2, 2);


답변

params 또한 단일 인수로 메소드를 호출 할 수 있습니다.

private static int Foo(params int[] args) {
    int retVal = 0;
    Array.ForEach(args, (i) => retVal += i);
    return retVal;
}

Foo(1);대신 Foo(new int[] { 1 });. 전체 배열이 아닌 단일 값을 전달해야하는 시나리오에서 속기에 유용 할 수 있습니다. 여전히 메소드에서 동일한 방식으로 처리되지만이 방법을 호출하기 위해 약간의 사탕을 제공합니다.


답변

params 키워드 자체를 추가하면 사용할 수없는 메소드를 호출하는 동안 여러 개의 매개 변수를 전달할 수 있음이 표시됩니다. 보다 구체적으로 :

static public int addTwoEach(params int[] args)
{
    int sum = 0;

    foreach (var item in args)
    {
        sum += item + 2;
    }

    return sum;
}

위의 메소드를 호출하면 다음 방법 중 하나로 호출 할 수 있습니다.

  1. addTwoEach()
  2. addTwoEach(1)
  3. addTwoEach(new int[]{ 1, 2, 3, 4 })

그러나 params 키워드를 제거 할 때 위의 세 번째 방법 만 잘 작동합니다. 첫 번째와 두 번째 경우에는 오류가 발생합니다.