C # 4.0은 선택적 out
또는 ref
인수를 허용합니까 ?
null
기본 설정 ( PHP에서 온 것)을 통해 참조를 통해 선택적 인수에 상당히 익숙해졌습니다. 어쨌든 null
인수를 채우는 테스트 ( 친숙한 사람들은 생각합니다preg_match()
) 어쨌든 기술적 인 관점에서 현재 이해 할 수 있습니다. 불가능하다. PHP와 C #은 비교할 수 없지만 여전히 " 좋은 "도구가 될 것이다.
C # 4.0은 선택적 out
또는 ref
인수를 허용합니까 ?
null
기본 설정 ( PHP에서 온 것)을 통해 참조를 통해 선택적 인수에 상당히 익숙해졌습니다. 어쨌든 null
인수를 채우는 테스트 ( 친숙한 사람들은 생각합니다preg_match()
) 어쨌든 기술적 인 관점에서 현재 이해 할 수 있습니다. 불가능하다. PHP와 C #은 비교할 수 없지만 여전히 " 좋은 "도구가 될 것이다.
답변:
이미 언급했듯이 이것은 단순히 허용되지 않으며 매우 의미가 있다고 생각합니다. 그러나 자세한 내용을 추가하려면 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에게 감사합니다.)
return SomeMethod(out string temp)
.. 자세한 내용은 여기를 참조하십시오 : blogs.msdn.microsoft.com/dotnet/2016/08/24/…
return SomeMethod(out _);
아니요, 그러나 다른 좋은 대안은 다음과 같이 메소드가 선택적 매개 변수에 일반 템플리트 클래스를 사용하도록하는 것입니다.
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
함수 호출이 종료되기 전에 의지가 호출 될 것이라고 가정 할 수 없으므로 변수를 명시 적으로 초기화해야합니다 .
모든 유스 케이스에 적합하지는 않지만 실제 유스 케이스 (단위 테스트를위한 데이터를 제공하는 함수 및 새로운 단위 테스트가 리턴 값에 존재하지 않는 일부 내부 상태에 액세스 해야하는 기능)에서는 잘 작동했습니다.
이건 어때?
public bool OptionalOutParamMethod([Optional] ref string pOutParam)
{
return true;
}
여전히 C #에서 매개 변수로 값을 전달해야하지만 선택적 ref 매개 변수입니다.
[Optional]
주석을 무시합니다 . 도움이되지 않습니다.
void foo(ref int? n)
{
return null;
}