문제

출력 매개변수를 언제 사용해야 하는지 이해가 안 되고, 두 개 이상의 유형을 반환해야 하는 경우 개인적으로 결과를 새 유형으로 래핑하는데, ​​외부보다 작업하기가 훨씬 쉽다는 것을 알았습니다.

이런 방법을 본 적이 있는데,

   public void Do(int arg1, int arg2, out int result)

그것이 실제로 의미가 있는 경우가 있습니까?

어때? TryParse, 왜 반환하지 않습니까? ParseResult 유형?아니면 최신 프레임워크에서 null 허용 유형을 반환합니까?

도움이 되었습니까?

해결책

당신이있을 때는 아웃이 좋습니다 TryNNN 함수는 기능이 성공하지 못하더라도 아웃 패러라미터가 항상 설정 될 것임이 분명합니다. 이를 통해 선언 한 로컬 변수가 NULL에 대한 코드에 나중에 수표를 작성하지 않고 설정되었다는 사실에 의존 할 수 있습니다. (아래의 주석은 매개 변수를 설정할 수 있음을 나타냅니다. null, 따라서 이것이 사실인지 아닌지 확인하기 위해 호출하는 기능에 대한 문서를 확인할 수 있습니다.) 코드를 조금 더 명확하고 읽기 쉽게 만듭니다. 또 다른 사례는 다음과 같은 방법의 조건에 따라 일부 데이터와 상태를 반환 해야하는 경우입니다.

public bool DoSomething(int arg1, out string result);

이 경우 리턴은 함수가 성공했는지 여부를 표시하고 결과가 OUT 매개 변수에 저장됩니다. 물론,이 예는 함수가 단순히 string, 그러나 당신은 아이디어를 얻습니다.

단점은 로컬 변수를 사용하려면 다음을 선언해야한다는 것입니다.

string result;
if (DoSomething(5, out result))
    UpdateWithResult(result);

대신에:

UpdateWithResult(DoSomething(5));

그러나 그것은 단점조차 없을 수도 있고, 당신이하려는 디자인에 달려 있습니다. DateTime의 경우 두 수단 (구문 분석 및 TryParse)이 제공됩니다.

다른 팁

대부분의 것들과 함께 그것은 달라집니다. 옵션을 살펴 보겠습니다

  • 원하는 것을 함수의 반환 값으로 반환 할 수 있습니다.
  • 여러 값을 반환하려고하거나 함수에 이미 리턴 값이있는 경우 매개 변수를 사용하거나 이러한 모든 값을 속성으로 노출시키는 새 복합 유형을 만들 수 있습니다.

TryParse의 경우, out param을 사용하는 것이 효율적입니다. - 당신은 16B의 오버 헤드 (32B 머신) 인 새로운 유형을 만들 필요가 없거나 통화 후 쓰레기를 수집 한 최종 비용이 발생할 필요가 없습니다. TryParse는 예를 들어 루프 내에서 호출 될 수 있습니다.
루프 내에서 호출되지 않는 함수의 경우 (즉, 성능은 큰 관심사가 아님) 단일 복합 객체를 반환하는 것은 '깨끗한'(보는 사람에 주관) 일 수 있습니다. 이제 익명 유형이 있습니다 동적 타이핑은 훨씬 쉬워 질 수 있습니다.

메모:

  1. out 매개 변수에는 따라야하는 몇 가지 규칙이 있습니다. 즉, 컴파일러는 기능이 종료되기 전에 값을 초기화하도록합니다. 따라서 tryparse
  2. tryxxx 패턴은 Params -Int32를 사용하는시기의 좋은 예입니다. int32.tryparse는 Parse가 실패했는지 알기 위해 예외를 잡는 것에 대해 불만을 제기 한 COZ 사람들에게 소개되었습니다. 또한 Parse가 성공할 경우에 따라 가장 가능성이 높은 것은 구문 분석 값을 얻는 것입니다. out param을 사용하여 다른 방법으로 구문 분석을 할 필요가 없습니다.

나는 tryparse와 같은 부울과 값을 모두 반환 해야하는 상황에 유용하지만 컴파일러가 다음과 같은 것을 허용한다면 좋을 것입니다.

bool isValid = int.TryParse("100", out int result = 0);

확실히, OUT 매개 변수는 게시 한 예에서 하나 이상의 값을 반환 해야하는 메소드가있을 때 사용하도록 의도됩니다.

public void Do(int arg1, int arg2, out int result)

하나의 값 만 반환하기 때문에 Out 매개 변수를 사용하는 것은 그다지 의미가 없으며, OUT 매개 변수를 제거하고 int 리턴 값을 넣으면 해당 메소드를 더 잘 사용할 수 있습니다.

public int Do(int arg1, int arg2)

아웃 매개 변수에 대한 몇 가지 좋은 점이 있습니다.

  1. 출력 매개 변수는 처음에는 할당되지 않은 것으로 간주됩니다.
    • 모든 매개 변수 ~ 해야 하다 메소드가 반환되기 전에 확실히 할당되면 할당을 놓친 경우 코드가 컴파일되지 않습니다.

결론적으로, 나는 기본적으로 내 개인 API 여러 리턴 값을 래핑하기 위해 별도의 유형을 생성하지 않고 공개 API에서는 TryParse 패턴과 일치하는 메소드에서만 사용합니다.

몇 년이 늦어서 답을 얻었습니다. Out (및 심판)도 귀하의 방법이 새로운 개체를 인스턴스화하기를 원하지 않으면 정말 유용합니다. 이는 방법에 대한 이하 마이크로 초 성능을 달성하려는 고성능 시스템에서 매우 관련이 있습니다. 인스턴베이션은 메모리 액세스 관점에서 비교적 비싸다.

값을 반환하기위한 유형을 만드는 것은 나에게 약간 고통스럽지 않습니다 :-) 먼저 값을 반환하기위한 유형을 만들어야합니다. 그런 다음 호출 방법에서 반환 된 유형에서 필요한 변수에 값을 할당해야합니다.

OUT 매개 변수는 SIMIPLER를 사용할 수 있습니다.

예, 말이됩니다. 예를 들어 이것을 가져 가십시오.

String strNum = "-1";
Int32 outNum;

if (Int32.TryParse(strNum, out outNum)) {
    // success
}
else {
    // fail
}

반환 값이있는 일반 기능에서 작업이 실패하면 무엇을 반환 할 수 있습니까? 실패를 나타 내기 위해 -1을 반환 할 수 없었습니다. 실패 퇴행 값과 처음부터 구문 분석 된 실제 값 사이에는 차별화가 없기 때문입니다. 이것이 우리가 부울 가치를 반환하여 성공했는지 확인하는 이유이며, 그렇다면 이미 안전하게 할당 된 "반품"값이 있습니다.

tryparse 함수의 Out 매개 변수로 NULL을 전달할 수 없다는 것이 짜증납니다.

그럼에도 불구하고, 나는 어떤 경우에는 두 개의 데이터가있는 새로운 유형을 반환하는 것을 선호합니다. 특히 그들이 대부분의 경우 관련이 없거나 한 조각이 한 순간에 단일 작업에만 필요할 때. tryparse 함수의 결과 값을 저장 해야하는 경우, 내가 다루어야 할 임의의 결과 및 value 클래스보다는 아웃 매개 변수를 갖는 것을 정말로 좋아합니다.

항상 유형을 생성한다면 애플리케이션이 너무 복잡해질 수 있습니다.

여기서 말했듯이 일반적인 사용 사례 중 하나는 TrySomething 성공에 대한 표시기로 부울을 반환한 다음 실제 값을 반환하려는 방법입니다.또한 if 문이 조금 더 깔끔하다는 것을 알았습니다. 어쨌든 세 가지 옵션 모두 대략 동일한 LOC를 갖습니다.

int myoutvalue;
if(int.TryParse("213",out myoutvalue){
    DoSomethingWith(myoutvalue);
}

vs.

ParseResult<int> myoutvalue = int.TryParse("213");
if ( myoutvalue.Success ) {
    DoSomethingWith(myoutvalue.Value);
}

vs.

int? myoutvalue = int.TryParse("213");
if(myoutvalue.HasValue){
    DoSomethingWith(myoutvalue.Value);
}

"Nullable 유형을 반환하지 않는 이유"는 다음과 같습니다.TryParse는 Framework 1.x부터 존재하는 반면 Nullable Types는 2.0과 함께 제공됩니다(Generics가 필요하므로).그렇다면 불필요하게 호환성을 깨뜨리거나 일부 유형에서 TryParse 간에 불일치가 발생하기 시작하는 이유는 무엇입니까?이미 존재하는 기능을 복제하기 위해 언제든지 자신만의 확장 메서드를 작성할 수 있습니다(참조 에릭 리퍼츠 포스트 일을 하거나 하지 않는 데 대한 추론을 포함하는 관련 없는 주제에 대해)

또 다른 사용 사례는 관련되지 않은 여러 값을 반환해야 하는 경우입니다. 그렇게 하면 메서드가 너무 많은 작업을 수행할 수 있다는 경고가 발생합니다.반면, 메소드가 비용이 많이 드는 데이터베이스나 웹 서비스 호출과 같고 결과를 캐시하려는 경우에는 그렇게 하는 것이 합리적일 수 있습니다.물론 유형을 생성할 수도 있지만 이는 애플리케이션에 유형이 하나 더 있다는 의미입니다.

나는 사용한다 밖으로 메소드 이름을 읽을 때 가독성에 대한 매개 변수는 때로는 메소드의 출력이 무엇이든간에, 특히 반환 결과 외에 명령을 실행하는 메소드의 경우 더 중요합니다.

StatusInfo a, b, c;

Initialize(out a);
Validate(a, out b);
Process(b, out c);

vs.

StatusInfo a = Initialize();
StatusInfo b = Validate(a);
StatusInfo c = Process(b);

적어도 나를 위해, 나는 스캔 할 때 각 라인의 처음 몇 문자를 많이 강조했습니다. 일부 "상태 인"변수가 선언된다는 것을 인정 한 후 첫 번째 예에서 무슨 일이 일어나고 있는지 쉽게 알 수 있습니다. 두 번째 예에서, 내가 가장 먼저 보는 것은 많은 StatusInfo가 검색된다는 것입니다. 방법이 어떤 영향을 미칠지 확인하려면 두 번째로 스캔해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top