문제

이는 C#에서 사용되는 규칙과 관련이 있습니다.

두 개의 매개 변수(X 및 Y 좌표)가 있는 메서드가 있습니다.이 좌표는 "타일"이 있을 수 있는 위치를 나타냅니다.타일이 이러한 좌표에 있는 경우 메서드는 타일의 번호를 반환합니다.이 좌표에 타일이 없으면 메서드가 어떻게 작동해야 하는지 궁금합니다.

세 가지 옵션이 표시됩니다.

  1. 예외를 사용하십시오.Method가 타일을 찾지 못할 때마다 예외가 발생할 수 있습니다.그러나 이러한 상황은 드문 일이 아니므로 이 옵션은 최악의 옵션입니다.
  2. 구식 C++ 방식으로 수행하고 타일이 없으면 -1을 반환합니다.
  3. 타일 ​​번호를 참조 매개변수로 만들고 메소드의 반환 유형을 불리언으로 변경하여 타일 유무를 표시합니다.그러나 이것은 나에게 약간 복잡해 보입니다.

그래서 내가 무엇을해야하니?

도움이 되었습니까?

해결책

-1을 반환합니다.

이는 C++ 규칙뿐만 아니라 .NET Framework에서도 일반적입니다.String.IndexOf와 같은 메서드 또는 목록을 나타내는 컨트롤을 위한 SelectedIndex와 같은 속성.

편집하다

자세히 설명하자면, 질문의 세 가지 옵션(예외, 반환 -1, 출력 매개변수) 중 -1을 반환하는 것이 좋습니다.예외는 예외적인 상황에 대한 것이며 Microsoft 코딩 지침에서는 가능한 경우 매개 변수를 사용하지 않을 것을 권장합니다.

내 생각에는 -1을 반환하는 것(항상 유효하지 않은 값인 경우), nullable int를 반환하거나 Tile 객체를 반환하는 것은 모두 허용 가능한 솔루션이며 앱의 나머지 부분과 가장 일관된 것을 선택해야 합니다.어떤 개발자도 다음 사항에 대해 조금이라도 어려움을 겪을 것이라고는 상상할 수 없습니다.

int tileNumber = GetTile(x,y);
if  (tileNumber != -1)
{
   ... use tileNumber ...
}


int? result = GetTile(x,y);
if (result.HasValue)
{
    int tileNumber = result.Value; 
   ... use tileNumber ...
}


Tile tile = GetTile(x,y);
if (tile != null)
{
   ... use tile ...
}

int를 사용하는 것이 "널 입력 가능 유형을 반환하는 것보다 훨씬 더 효율적"이라는 Peter Ruderman의 의견을 이해하는지 잘 모르겠습니다.나는 어떤 차이도 무시할 것이라고 생각했을 것입니다.

다른 팁

null을 반환하고 호출 코드에서 이를 확인할 수 있습니다.

물론 nullable 유형을 사용해야 합니다.

int? i = YourMethodHere(x, y);

예외는 예외적인 경우에 대한 것이므로 예외를 사용하는 경우는 다음과 같습니다. 모두 다 아는 그리고 예상되는 오류 상황은 "나쁨"입니다.또한 이제 이 오류 상황이 발생할 것으로 예상하기 때문에 특히 이 오류를 처리하기 위해 모든 곳에서 try-catch를 가질 가능성이 더 높습니다.

유일한 오류 조건(예: -1)이 실제 값과 혼동될 수 있는 경우 반환 값을 매개변수로 만드는 것이 허용됩니다.음수 타일 번호를 가질 수 있다면 이것이 더 좋은 방법입니다.

nullable int는 참조 매개변수에 대한 가능한 대안이지만 이를 사용하여 개체를 생성하므로 "오류"가 일상적인 경우 참조 매개변수보다 이 방식으로 더 많은 작업을 수행할 수 있습니다.Roman이 다른 곳의 주석에서 지적했듯이 C#과 C#이 있을 것입니다.VB 문제 널 입력 가능 유형 C#처럼 멋진 구문 설탕을 제공하기에는 VB에 너무 늦게 도입되었습니다.

타일이 음수가 아닐 수만 있다면 -1을 반환하는 것이 오류를 나타내는 허용 가능한 전통적인 방법입니다.또한 성능과 메모리 측면에서 비용이 가장 저렴합니다.


고려해야 할 또 다른 것은 자기 문서화입니다.-1을 사용하고 예외를 적용하는 것이 관례입니다.개발자가 이를 인지할 수 있도록 문서를 작성해야 합니다.사용하기 int? return 또는 참조 매개변수는 자체적으로 더 잘 설명되지만 그렇지 않습니다. 필요하다 개발자가 오류 상황을 처리하는 방법을 알 수 있는 문서입니다.물론이죠 :) 매일 치실을 관리하는 것처럼 항상 문서를 작성해야 합니다.

null 허용 반환 값을 사용하세요.

int? GetTile(int x, int y) {
   if (...)
      return SomeValue;
   else
      return null;
}

이것이 가장 명확한 해결책입니다.

메서드가 기본 타일 개체에 액세스할 수 있는 경우 타일 개체 자체를 반환하거나 그러한 타일이 없는 경우 null을 반환할 수도 있습니다.

나는 옵션 2를 선택하겠습니다.맞습니다. 이러한 일반적인 경우에 예외를 던지는 것은 성능에 좋지 않을 수 있으며 out 매개변수를 사용하고 true 또는 false를 반환하는 것은 유용하지만 읽기에는 까다롭습니다.

또한 생각해 보세요. string.IndexOf() 방법.아무것도 발견되지 않으면 -1을 반환합니다.나는 그 예를 따를 것입니다.

상당히 일반적인 C# 접근 방식이므로 -1을 반환할 수 있습니다.그러나 클릭한 타일을 실제로 반환하고 타일을 클릭하지 않은 경우 싱글톤 NullTile 인스턴스에 대한 참조를 반환하는 것이 더 나을 수 있습니다.이 방법을 사용하면 반환되는 각 값에 구체적인 의미를 부여할 수 있다는 이점이 있습니다. 이는 단순히 숫자 값 외에는 본질적인 의미가 없는 숫자가 되는 것이 아닙니다.'NullTile' 유형은 그 의미가 매우 구체적이므로 코드를 읽는 다른 독자가 의심할 여지가 거의 없습니다.

가장 좋은 옵션은 부울을 반환하거나 null을 반환하는 것입니다.

예를 들어

bool TryGetTile(int x, int y, out int tile);

또는,

int? GetTile(int x, int y);

"TryGetValue" 패턴을 선호하는 데는 여러 가지 이유가 있습니다.우선, 부울 값을 반환하므로 클라이언트 코드는 매우 간단합니다. 예:if (TryGetValue(out someVal)) { /* 일부 코드 */ }.이를 하드 코딩된 센티널 값 비교(-1, 0, null, 특정 예외 집합 포착 등)가 필요한 클라이언트 코드와 비교해 보세요. "마법의 숫자"는 이러한 디자인으로 빠르게 나타나고 긴밀한 결합을 고려하면 집안일.

센티널 값, null 또는 예외가 예상되는 경우 어떤 메커니즘이 사용되는지에 대한 문서를 확인하는 것이 절대적으로 중요합니다.문서가 존재하지 않거나 액세스할 수 없는 경우(일반적인 시나리오) 다른 증거를 기반으로 추론해야 합니다. 잘못된 선택을 하면 단순히 null 참조 예외나 기타 잘못된 결함이 발생하도록 설정하는 것입니다.반면 TryGetValue() 패턴은 이름과 메서드 서명만으로 자체 문서화에 매우 가깝습니다.

나는 귀하가 질문한 질문에 대해 내 자신의 의견을 가지고 있지만 위에 명시되어 있으며 이에 따라 투표했습니다.

귀하가 묻지 않은 질문에 대해 또는 적어도 위의 모든 답변에 대한 확장으로:유사한 상황에 대한 솔루션을 앱 전체에서 일관되게 유지하겠습니다.즉, 결정한 답변이 무엇이든 앱 내에서 동일하게 유지하세요.

메서드가 하위 수준 라이브러리의 일부인 경우 표준 .NET 설계에 따라 메서드에서 예외가 발생하도록 지정될 수 있습니다.

이것이 .NET 프레임워크가 일반적으로 작동하는 방식입니다.더 높은 수준의 호출자는 예외를 포착해야 합니다.

그러나 UI 이벤트에 응답하기 때문에 성능에 영향을 미치는 UI 스레드에서 이 작업을 수행하는 것 같으므로 Jay Riggs가 이미 제안한 대로 null을 반환하고 호출자가 null 반환 값을 확인하는지 확인합니다.

나는 그것을 두 가지 방법으로 나눌 것입니다.같은 것을 가지고 CheckTileExists(x,y) 그리고 GetTile(x,y).전자는 주어진 좌표에 타일이 있는지 여부를 나타내는 부울을 반환합니다.두 번째 방법은 본질적으로 원래 게시물에서 언급한 방법입니다. 단, 잘못된 좌표가 제공되면 예외가 발생해야 합니다(발신자가 먼저 호출하지 않았음을 나타냄). CheckTileExists(), 따라서 이는 합법적으로 예외적인 상황입니다.속도를 위해 이 두 메서드가 캐시를 공유하여 차례로 호출되는 경우 오버헤드가 발생하도록 하는 것이 좋습니다. GetTile() 기능은 미미할 것입니다.이러한 메서드를 추가하기에 적합한 개체가 이미 있는지 아니면 새 클래스에 두 개의 메서드를 만들어야 하는지 모르겠습니다.IMHO, 이 접근 방식의 성능 저하는 무시할 수 있으며 코드 명확성의 증가는 그보다 훨씬 큽니다.

당신이 만든(또는 만들 수 있었던) 것이 가능합니까? Tile 좌표에서 참조되는 객체는 무엇입니까?그렇다면 해당 타일에 대한 참조를 반환하거나 null 주어진 좌표에 타일이 없는 경우:

public Tile GetTile(int x, int y) {
    if (!TileExists(x, y)) 
        return null;
    // ... tile lookup here...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top