문제

예를 들어 몇 가지 비슷한 방법이 있습니다. 계산 지점 (...) 및 계산 텔리리스 토프 포인트 (...). 때때로 그들은 성공하지 못할 수 있으며,이를 발신자에게 표시해야합니다. 일반 목록을 반환하는 CalculatEListOfPoints의 경우 빈 목록을 반환 할 수 있으며 발신자가이를 확인해야합니다. 그러나 포인트는 값 유형이므로 Null을 반환 할 수 없습니다.

이상적으로는 비슷한 방법을 '외모'하는 방법을 원합니다. 하나의 해결책은 그것들을 다음과 같이 정의하는 것입니다

public Point CalculatePoint(... out Boolean boSuccess);
public List<Point> CalculateListOfPoints(... out Boolean boSuccess);

아니면 포인트를 반환하기 위해? 계산 지점의 경우, 실패를 나타 내기 위해 NULL을 반환합니다. 그것은 불가능한 유형으로 돌아 가야한다는 것을 의미합니다.

또 다른 경로는 부울 Bosuccess를 반환하고 결과 (포인트 또는 목록)를 'Out'매개 변수로 사용하고 TryTocalCulatePoint 또는 무언가를 호출하는 것입니다.

모범 사례는 무엇입니까?

편집 : 흐름 제어에 예외를 사용하고 싶지 않습니다! 때때로 실패가 예상됩니다.

도움이 되었습니까?

해결책

개인적으로, 나는 tryparse ()와 동일한 아이디어를 사용할 것이라고 생각합니다 : Out 매개 변수를 사용하여 실제 값을 출력하고 부울이 성공했는지 여부를 나타내는 부울을 반환합니다.

public bool CalculatePoint(... out Point result);

나는 "정상적인"동작에 예외를 사용하는 팬이 아닙니다 (일부 항목에서 기능이 작동하지 않을 것으로 예상되는 경우).

다른 팁

왜 실패했을까요? 그것이 발신자가 한 일 때문이라면 (즉, 제공된 인수) 인수를 던지는 것이 전적으로 적절합니다. 예외를 피하는 시도 [...] 방법은 괜찮습니다.

그래도 예외를 던지는 버전을 제공하는 것이 좋은 생각이라고 생각하므로 항상 좋은 데이터를 제공 할 것으로 기대하는 발신자는 틀린 경우 적절하게 강력한 메시지 (예외)를 받게됩니다.

또 다른 대안은 예외를 던지는 것입니다. 그러나 일반적으로 "예외적 인 경우"에는 예외를 제외하고 싶다.

실패 사례가 공통적이면 (예외적이지 않은 경우) 이미 두 가지 옵션을 나열했습니다. 편집하다: 프로젝트에는 이러한 비 법적 사례를 처리하는 방법 (성공 여부 또는 객체를 반환 해야하는 경우)과 같은 협약이있을 수 있습니다. 기존 협약이 없다면 LucasBFR에 동의하고 성공을 거두었다고 제안합니다 (TryParse (...)가 설계된 방법에 동의 함).

실패가 특정한 이유가 있다면 NULL 또는 BOOL을 반환하고 매개 변수가 있다고 생각합니다. 그러나 실패에 관계없이 NULL을 반환하면 권장하지 않습니다. 예외는 무언가가 실패한 이유를 포함하여 풍부한 정보 세트를 제공합니다. 다시 돌아 오는 모든 것이 널이라면 데이터가 잘못 되었기 때문에 기억이 부족하거나 다른 이상한 행동이 부족한 지 어떻게 알 수 있습니까?

.NET에서도 TryParse에는 구문 분석 형제가 있으므로 원하는 경우 예외를 얻을 수 있습니다.

트리 좀 방법을 제공하면 실패시 예외를 던진 방법도 제공 할 것입니다. 그런 다음 발신자에게 달려 있습니다.

내가 사용한 모델은 MS가 다양한 클래스의 tryparse 방법과 동일한 모델입니다.

원래 코드 :
공개 포인트 계산 점 (... 부울 bosuccess);
공개 목록 CalculatElistofpoints (... 부울 bosuccess);

공개 bool 계산 점 (... out (또는 ref) 포인트 계산 값)로 변합니다.
public bool calculatelistofpoints (... out (또는 ref) 목록 계산 values);

기본적으로 성공/실패를 반환 값으로 만듭니다.

요약하기 위해 몇 가지 접근 방식이 있습니다.

  1. 리턴 유형이 포인트와 같은 값 유형 인 경우 C#의 무효 기능을 사용하고 포인트를 반환합니까? (일명 Nullable), 그렇게하면 여전히 실패로 Null을 반환 할 수 있습니다.
  2. 실패가있을 때 예외를 던지십시오. "예외적 인"것이 무엇인지에 관한 모든 논쟁/토론은 무시 요점이며, API이며, 예외적 인 행동을 결정합니다.
  3. Int32와 같은 기본 유형에서 Microsoft가 구현 한 것과 유사한 모델을 채택하고 계산 점 및 trycalculatepoint (int32.parse 및 int32.tryparse)를 제공하고 하나의 던지기와 하나는 bool을 반환합니다.
  4. 두 가지 속성, 부울 성공과 일반 유형 값이있는 방법에서 일반 구조를 반환하십시오.

시나리오에 따라 나는 널을 반환하거나 예외가 나에게 "가장 깨끗한"것처럼 보이며 내가 일하는 회사의 기존 코드베이스에 가장 적합한 예외를 사용하는 경향이 있습니다. 따라서 개인 모범 사례는 1과 2에 접근 할 것입니다.

그것은 주로 방법의 동작과 사용에 달려 있습니다.

실패가 일반적이고 중요하지 않은 경우, 방법이 성공을 나타내는 부울을 반환하고 결과를 전달하기 위해 아웃 매개 변수를 사용하도록하십시오. 해시에서 키를 찾아서 데이터를 사용할 수 없을 때 비 블로킹 소켓의 데이터를 읽으려고 시도하면 이러한 모든 예제는 해당 범주에 속합니다.

실패가 예상치 못한 경우 결과를 직접 반환하고 예외로 오류를 전달하십시오. 파일 읽기 전용을 열면 TCP 서버에 연결하는 것이 좋은 후보입니다.

때로는 두 가지 방법이 모두 의미가 있습니다 ...

반품 포인트. 구조 생성이 성공했는지 확인하고 싶을 때 특수 필드를 반환하는 것은 .NET 디자인 패턴입니다. 피하다 밖으로 가능하면 매개 변수.

public static readonly Point Empty

내가 실험하고있는 패턴은 a 아마도. 그것은 의미론이있다 tryparse 패턴이지만 Null-Return-on-Error 패턴과 유사한 시그니처.

나는 아직 어떤 식 으로든 확신하지는 않지만, 당신의 집단적 고려를 위해 그것을 제안합니다. 메소드 호출 전에 정의 된 변수가 메소드의 호출 사이트에서 아웃 매개 변수를 유지하기 위해 변수를 정의 할 필요가 없다는 이점이 있습니다. 또한 연장 할 수도 있습니다 오류 또는 메시지 실패의 이유를 나타내는 수집.

어쩌면 수업은 다음과 같이 보입니다.

/// <summary>
/// Represents the return value from an operation that might fail
/// </summary>
/// <typeparam name="T"></typeparam>
public struct Maybe<T>
{
    T _value;
    bool _hasValue;


    public Maybe(T value)
    {
        _value = value;
        _hasValue = true;
    }

    public Maybe()
    {
        _hasValue = false;
        _value = default(T);
    }


    public bool Success
    {
        get { return _hasValue; }
    }


    public T Value
    {
        get 
            { // could throw an exception if _hasValue is false
              return _value; 
            }
    }
}

모범 사례는 반환 가치가 성공을 의미한다고 말합니다. 예외 실패를 의미합니다.

당신이 사용하지 말아야한다는 예제에 이유가 없습니다. 예외 실패시.

예외를 사용하는 것은 경우에도 나쁜 생각 (특히 서버를 작성할 때)입니다. 방법의 두 가지 맛이 필요합니다. 또한해야 할 일을 나타내는 사전 클래스를 살펴보십시오.

// NB:  A bool is the return value. 
//      This makes it possible to put this beast in if statements.
public bool TryCalculatePoint(... out Point result) { }

public Point CalculatePoint(...)
{
   Point result;
   if(!TryCalculatePoint(... out result))
       throw new BogusPointException();
   return result;
}

두 세계의 최고!

bool trysomething ()은 적어도 연습이며 .NET의 구문 분석 방법에 적합하지만 일반적으로 좋아하지 않는다고 생각합니다.

예외를 던지는 것은 종종 좋은 일이지만, 많은 정상적인 상황에서 일어날 것으로 예상되는 상황에 사용해서는 안되며 관련된 성능 비용이 있습니다.

가능한 경우 널 리턴하는 것은 대부분의 경우 예외를 원하지 않을 때 괜찮습니다.

하지만 - 당신의 접근 방식은 약간의 절차입니다 - PointCalculator 클래스와 같은 것을 만드는 것은 어떻습니까? 필요한 데이터를 생성자의 매개 변수로 취하는 것은 무엇입니까? 그런 다음 CalculatePoint를 호출하고 속성 (포인트 및 성공을위한 별도의 속성)을 통해 결과에 액세스하십시오.

@Kevin은 예외적 인 경우에 예외가 있다고 언급했기 때문에 예상되는 일이있을 때 예외를 제외하고 싶지 않습니다.

당신은 '실패'에 기대되는 것을 반환해야합니다. 일반적으로 Null은 내가 선택한 나쁜 수익입니다.

방법에 대한 문서는 사용자에게 데이터가 예상 할 내용을 알려야합니다. 계산하지 않습니다.

우리는 한때 모든 공개 방법이 True (성공적으로 실행) 또는 False (오류가 발생 함)를 반환 한 전체 프레임 워크를 작성했습니다. 값을 반환 해야하는 경우 출력 매개 변수를 사용했습니다. 대중의 믿음과는 달리, 이러한 프로그래밍 방식은 실제로 많은 코드를 단순화했습니다.

포인트와 함께, 당신은 다시 포인트를 보낼 수 있습니다. 이제이 모든 것이 실제로 X와 Y 값에 대해 0의 포인트를 반환하는 것입니다. 따라서 유효한 반환 값이 될 수 있다면, 나는 그것으로부터 멀리 떨어져 있지만, 당신의 메소드가 a (0,0) 포인트를 반환하지 않으면 그런 다음 사용할 수 있습니다.

죄송합니다. 방금 널리 이시는 유형을 기억했습니다. 당신은 그것을보아야합니다. 오버 헤드가 무엇인지 잘 모르겠습니다.

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