[c#-4.0] C # 4.0 선택적 out / ref 인수

C # 4.0은 선택적 out또는 ref인수를 허용합니까 ?



답변

이미 언급했듯이 이것은 단순히 허용되지 않으며 매우 의미가 있다고 생각합니다. 그러나 자세한 내용을 추가하려면 C # 4.0 Specification 섹션 21.1 의 인용문을 참조하십시오 .

생성자, 메서드, 인덱서 및 대리자 형식의 형식 매개 변수는 선택적으로 선언 될 수 있습니다.

고정 매개 변수 :
    속성 opt 매개 변수 수정 자 opt 유형 식별자 default-argument opt
default-argument :
    = expression

  • 고정 매개 변수 A를 기본 인수는 입니다 선택적 매개 변수 반면, 고정 매개 변수 없이 기본 인수는 A는 필수 매개 변수 .
  • formal-parameter-list 의 선택적 매개 변수 뒤에 필수 매개 변수가 표시 될 수 없습니다 .
  • ref또는 out매개 변수는 사용할 수 없습니다 기본 인수를 .

답변

아니.

해결 방법은 out / ref 매개 변수 가없고 현재 메서드를 호출하는 다른 메서드로 오버로드하는 것 입니다.

public bool SomeMethod(out string input)
{
    ...
}

// new overload
public bool SomeMethod()
{
    string temp;
    return SomeMethod(out temp);
}

업데이트 : C # 7.0 인 경우 다음을 단순화 할 수 있습니다.

// new overload
public bool SomeMethod()
{
    return SomeMethod(out _);    // declare out as an inline discard variable
}

(이 점을 지적 해준 @Oskar / @Reiner에게 감사합니다.)


답변

아니요, 그러나 다른 좋은 대안은 다음과 같이 메소드가 선택적 매개 변수에 일반 템플리트 클래스를 사용하도록하는 것입니다.

public class OptionalOut<Type>
{
    public Type Result { get; set; }
}

그런 다음 다음과 같이 사용할 수 있습니다.

public string foo(string value, OptionalOut<int> outResult = null)
{
    // .. do something

    if (outResult != null) {
        outResult.Result = 100;
    }

    return value;
}

public void bar ()
{
    string str = "bar";

    string result;
    OptionalOut<int> optional = new OptionalOut<int> ();

    // example: call without the optional out parameter
    result = foo (str);
    Console.WriteLine ("Output was {0} with no optional value used", result);

    // example: call it with optional parameter
    result = foo (str, optional);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);

    // example: call it with named optional parameter
    foo (str, outResult: optional);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional.Result);
}


답변

실제로 C #에서 허용하는 방법이 있습니다. 이것은 C ++로 돌아가고 C #의 멋진 Object-Oriented 구조를 위반합니다.

이 방법을주의해서 사용하십시오!

선택적 매개 변수를 사용하여 함수를 선언하고 작성하는 방법은 다음과 같습니다.

unsafe public void OptionalOutParameter(int* pOutParam = null)
{
    int lInteger = 5;
    // If the parameter is NULL, the caller doesn't care about this value.
    if (pOutParam != null)
    {
        // If it isn't null, the caller has provided the address of an integer.
        *pOutParam = lInteger; // Dereference the pointer and assign the return value.
    }
}

그런 다음 다음과 같이 함수를 호출하십시오.

unsafe { OptionalOutParameter(); } // does nothing
int MyInteger = 0;
unsafe { OptionalOutParameter(&MyInteger); } // pass in the address of MyInteger.

이를 컴파일하려면 프로젝트 옵션에서 안전하지 않은 코드를 활성화해야합니다. 이것은 일반적으로 사용해서는 안되는 매우 해킹 된 솔루션이지만 이상한 이상한 신비한 관리 영감을 얻은 결정에 정말로 C #에서 선택적 매개 변수가 필요하다면 그렇게 할 수 있습니다.


답변

ICYMI는 : 열거 된 C # 7.0의 새로운 기능에 포함 된 여기에 , “폐기”가 지금의 형태 _의 매개 변수 아웃으로 허용, 당신은 당신이 걱정하지 않는 매개 변수를 무시하도록하려면 :

p.GetCoordinates(out var x, out _); // I only care about x

PS “out var x”부분과 혼동되는 경우 링크에서 “Out Variables”에 관한 새로운 기능을 읽으십시오.


답변

아니요, 대신 대리인 (예 :)을 사용할 수 있습니다 Action.

선택적 매개 변수를 원한다고 생각하는 상황에 직면했을 때 Robin R의 대답에서 부분적으로 영감을 얻은 대신 Action대리자 를 사용했습니다 . Action<int>차이점과 유사성을 보여주기 위해 그의 예제 코드를 빌려 사용하도록 수정했습니다 .

public string foo(string value, Action<int> outResult = null)
{
    // .. do something

    outResult?.Invoke(100);

    return value;
}

public void bar ()
{
    string str = "bar";

    string result;
    int optional = 0;

    // example: call without the optional out parameter
    result = foo (str);
    Console.WriteLine ("Output was {0} with no optional value used", result);

    // example: call it with optional parameter
    result = foo (str, x => optional = x);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);

    // example: call it with named optional parameter
    foo (str, outResult: x => optional = x);
    Console.WriteLine ("Output was {0} with optional value of {1}", result, optional);
}

이는 선택적 변수가 소스에 일반 int로 표시되는 이점이 있습니다 (컴파일러는 사용자 정의 클래스로 명시 적으로 래핑하지 않고 클로저 클래스로 래핑합니다).

컴파일러는 Action함수 호출이 종료되기 전에 의지가 호출 될 것이라고 가정 할 수 없으므로 변수를 명시 적으로 초기화해야합니다 .

모든 유스 케이스에 적합하지는 않지만 실제 유스 케이스 (단위 테스트를위한 데이터를 제공하는 함수 및 새로운 단위 테스트가 리턴 값에 존재하지 않는 일부 내부 상태에 액세스 해야하는 기능)에서는 잘 작동했습니다.


답변

out 매개 변수없이 오버로드 된 메서드를 사용하여 C # 6.0 이하의 out 매개 변수가있는 메서드를 호출하십시오. C # 4.0에 선택적 출력 매개 변수가 있는지 여부를 구체적으로 물었을 때 .NET Core 용 C # 7.0이이 스레드에 대한 정답 인 이유를 잘 모르겠습니다. 내 대답은 아니오 야!