모범 사례 : 기능 반환 값 또는 BYREF 출력 매개 변수?
-
05-07-2019 - |
문제
FindSpecificRowValue라는 기능이 있으며 데이터 가능성을 가져와 특정 값이 포함 된 행 번호를 반환합니다. 해당 값을 찾지 못하면 호출 함수를 표시하고 싶습니다.
가장 좋은 방법은 다음과 같습니다.
- 찾을 수없는 경우 false, 찾은 경우 true 및 byref/output 매개 변수로 찾은 행 번호를 반환하는 함수를 작성하십시오.
- int를 반환하는 함수를 작성하고 행 값을 찾을 수없는 경우 -999를 전달하십시오. 행 번호가있는 경우?
해결책
개인적으로 나는 그 방법 이름으로하지 않을 것입니다.
대신 두 가지 방법을 만들 것입니다.
TryFindSpecificRow
FindSpecificRow
이것은 int32.parse/tryparse의 패턴을 따릅니다. C#에서는 다음과 같이 보일 수 있습니다.
public static Boolean TryFindSpecificRow(DataTable table, out Int32 rowNumber)
{
if (row-can-be-found)
{
rowNumber = index-of-row-that-was-found;
return true;
}
else
{
rowNumber = 0; // this value will not be used anyway
return false;
}
}
public static Int32 FindSpecificRow(DataTable table)
{
Int32 rowNumber;
if (TryFindSpecificRow(table, out rowNumber))
return rowNumber;
else
throw new RowNotFoundException(String.Format("Row {0} was not found", rowNumber));
}
편집하다: 질문에 더 적합하도록 변경되었습니다.
다른 팁
실패한 기능은 예외를 제외해야합니다.
실패가 예상 흐름의 일부인 경우 대역 밖에서의 값이 무엇인지 사전 결정 할 수없는 경우를 제외하고는 밴드 값을 벗어난 값을 반환하는 것이 정상입니다.이 경우 예외를 던져야합니다.
옵션 중에서 선택해야한다면 옵션 2를 선택하지만 -999가 아닌 상수를 사용합니다 ...
반환 값을 다음과 같이 정의 할 수도 있습니다 무효 그리고 아무것도 발견되지 않으면 아무것도 돌려주지 않습니다.
옵션 2를 선택할 것입니다. 비록 -999가 아닌 -1 만 사용할 것이라고 생각합니다.
Richard Harrison은 명명 된 Constant가 Bare -1 또는 -999보다 낫다는 것이 옳습니다.
나는 2 또는 반환 값이 값이 발견되었는지 여부를 나타내는 다른 변형과 함께 갈 것입니다.
함수가 반환하는 행의 값 (또는 참조를 제공)은 이미 값이 발견되었는지 여부를 나타냅니다. 값이 발견되지 않은 경우 값이 포함되지 않은 행 번호를 제공하는 것은 의미가없는 것 같습니다. 따라서 반환 값은 -1이거나 NULL이거나 특정 언어에 적합한 다른 값이어야합니다. 그렇지 않으면 행 번호가 반환되었다는 사실은 값이 발견되었음을 나타냅니다.
따라서, 값이 발견되었는지 여부를 나타내는 별도의 반환 값이 필요하지 않은 것 같습니다. 그러나 특정 언어의 관용구에 맞고 기능 호출이 수행되는 방식이 적합한 경우 1 형이 적절할 수 있습니다.
2)와 함께 가십시오.
BTW -1은 -999보다 더 수용 가능하고 널리 사용되는 "마술 번호"가 널리 사용됩니다. 이것이 바로 "정확한"유일한 이유 (이유에 사용 된 인용문)입니다.
그러나 이것의 대부분은 당신이 기대하는 것과 관련이 있습니다. 항목은 항상 거기에 있어야하지만 어디에 있는지 모르십니까? 이 경우 색인을 정상적으로 반환하고 없으면 오류/예외를 던지십시오.
이 경우 항목이 없을 수 있으며 괜찮은 조건입니다. DataTable에 바인딩하는 GridView의 선택되지 않은 값에 대한 오류 트랩입니다.
아직 언급되지 않은 또 다른 몇 가지 가능성 :
// Method 1: Supports covariance; can return default<T> on failure. T TryGetThing(ref bool success); // Method 2: Does not support covariance, but may allow cleaner code in some cases // where calling code would use some particular value in in case of failure. T TryGetThing(T DefaultValue); // Method 3: Does not support covariance, but may allow cleaner code in some cases // where calling code would use some particular value in case of failure, but should // not take the time to compute that value except when necessary. T TryGetThing(Func<T> AlternateGetMethod); // Method 4: Does support covariance; ErrorMethod can throw if that's what should // happen, or it can set some flag which is visible to the caller in some other way. T TryGetThing(Action ErrorMethod);
첫 번째 접근법은 Covariant 인터페이스에 대한 지원이 존재하기 전날 Microsoft가 개발 한 방법의 반대입니다. 마지막은 어떤면에서 가장 다재다능하지만, 사용될 때마다 몇 가지 새로운 GC 객체 인스턴스 (예 : 폐쇄 및 대표)를 생성해야 할 가능성이 높습니다.