2011-11-01 3 views
1

내 코드에 오류 처리를 넣고 싶습니다. 나는 다음과 같은 예를 들어 그것을 할 방법을 알아낼 수 없습니다 : 'float 메서드'에 대해 null을 반환하는 방법 - 오류 처리

public class DataPoints 
{ 
    public PointF[] RawData {get; set;} //raw measurement pairs 
    public float xMax; //max value on X axis 
    public float yMax; //max value on Y axis 

    public float GetMaxX() 
    { 
     if(RawData == null) 
     { 
      throw new NullReferenceException(); 
      return null; //THIS does not compile! I want to exit the method here 
     } 

    //DO other stuff to find max X 
    return MAX_X; //as float 
    } 
} 

그래서 생각이, 내가 RawData가 이미 설정 한 다음 GetMaxX() 방법으로 물건의 나머지 부분을 할 경우 확인해야합니다. 이것은 좋은 습관입니까? 이 경우 당신은 무엇을 할 것입니까?

+0

은 여기 (null의 유효하지 않은)는 부동 소수점 값을 반환 할 것으로 예상 – V4Vendetta

답변

4

두 가지 문제는이 코드가 있으며,

우선 당신이 반환 다음 예외 던지고있어 - 리턴 문이 방법의 나머지 부분의 실행을 중지합니다 예외로 충돌되지 않을 것이다, return 문을 불필요하게 만듭니다.

둘째, 반환 유형이 float 인 경우 null을 반환 할 수 없습니다. 반환 유형을 float으로 변경해야합니다. 그것은 실제 오류의 경우 경우 당신은 단지를 제외하고 이동 할 수있는 일은 없기 때문에, 그래서 하나

을 :

public float GetMaxX() 
    { 
     if(RawData == null) 
      throw new NullReferenceException(); 

    //DO other stuff to find max X 
    return MAX_X; //as float 
    } 

또는 대안이 널 (null)을 반환하고 예외를 드롭 (nullable types 참조) :

public float? GetMaxX() 
    { 
     if(RawData == null) 
      return null; 

    //DO other stuff to find max X 
    return MAX_X; //as float 
    } 

개인적으로, RawData되는 널 (null) 후 발생해서는 안 나는 예외를 던져 말을하고, 호출 코드에 던져 경우 예외를 처리 오류 상태/예외적 인 상황 인 경우.

대체 접근법은 RawData의 초기화를 생성자를 통해 강제로 수행하고 RawData을 비공개 (또는 적어도 설정자)로 만들고 예외를 throw하는 것입니다. RawData이 이전에 설정되었다고 가정 할 수 있기 때문에 예외를 던지거나 null을 확인하는 클래스의 다른 논리는 그대로 둡니다. 의 라인을 따라 뭔가 결과

:

public class DataPoints 
{ 
    private readonly PointF[] rawData; //raw measurement pairs 
    public float xMax; //max value on X axis 
    public float yMax; //max value on Y axis 

    public DataPoints(PointF[] rawData) 
    { 
     if (rawData == null) 
      throw new ArgumentNullException("rawData"); 

     this.rawData = rawData; 
    } 

    public float GetMaxX() 
    { 
     //DO other stuff to find max X 
     return MAX_X; //as float 
    } 
} 
2

당신이 시도하는지의 올바른 버전

public float GetMaxX() 
    { 
     if(RawData == null) 
     { 
     throw new NullReferenceException(); 
     } 

     //DO other stuff to find max X 
     return MAX_X; //as float 
    } 

플로트 값이기 때문에 return 문 컴파일하지 않을 것이다, 그래서 당신은 return 문이 어쨌든 실행되지 않습니다 예외를 throw하는 경우 nullable 유형 float를 사용하지 않으면 null이 될 수없는 유형을?

개인적으로 제공 한 코드 샘플에서 예외가 발생합니다. 공개 설정자를 통해 RawData 객체가 노출되어 있으므로 GetMaxX가 호출 될 때 null이 아니라는 보장은 없습니다. 그런 다음 예외를 스택 위로 전파하여 모든 수준에서 포착 할 수 있습니다. 반면 반환 형식을 nullable로 설정하면 호출 코드에 추가 검사를 추가하여 메서드가 null을 반환했는지 여부를 확인하고 적절하게 처리해야합니다.

1

난 당신이 오류가 발생하는 경우에 수행 할 작업에 대한 명확하지 않다. 예외를 던지거나 null을 반환 하시겠습니까?

일반적으로 예외를 발생시키는 것은 호출자가 더 잘 알고 있어야하고 복구하려고하지 않으려는 경우입니다. 호출자가 처리를 정리하게하십시오.

null을 반환하는 것은 호출자가 RawData를 초기화하지 않은 좋은 이유가있는 경우입니다. 이는 귀하의 경우에 적합합니다. 이를 위해 당신이 당신이 정말로 아무것도가 초기화되지 않을 때 폭파하려는 경우

public float? GetMaxX() 

이 필요합니다, 당신의 생성자에서 매개 변수로 RAWDATA을 넣어.

1

throw 예외 문 아래에있는 return 문을 제거 할 수 있습니다. 예외가 throw 될 때마다 메서드에서 다른 명령문이 실행되지 않습니다 (finally 블록은 예외이지만이 컨텍스트에서는 의미가 없습니다).

함수에 대한이 문제를 제외하고는 RawData 속성이 공개적으로 액세스 할 수 있다는 인수가 있습니다. 일반적으로 그런 컬렉션을 열지 않는 것이 좋습니다. @ sq33G가 암시 하듯이 RawData를 생성자 매개 변수로 전달하여 유효한 개체를 가질 수 있습니다. 그리고 무효 어레이가 전달 될 때 생성자에서 일찍 실패 할 수 있습니다 (null, 크기가 0 일 수도 있습니다). 이 RawSata 클래스의 외부에서 액세스 할 수 있음이 켜지지 않으면

private PointF[] _rawData; 

public DataPoints(PointF[] rawData) 
{ 
    if(rawData == null || rawData.Length == 0) 
     throw new ArgumentException("RawData should not be null and should contain at least one element"); 
    this._rawData = rawData; 
} 

, 난 당신이 배열 자체 (그래서 아무 세터)이나 그 내용이 변경 될 수 없다 둘 다있는 방식으로 그것을하는 것이 좋습니다. IEnumerable을 사용하는 것이 올바른 방법입니다.

public IEnumerable<PointF> RawData 
{ 
    get { return _rawData; } 
} 
1

값을 반환하는 데 항상 메소드가 필요하지는 않습니다. 특히 예외를 throw하여 을 종료 할 수도 있습니다 (이 경우 값은 반환되지 않습니다). 당신은 당신의 예에서 규칙 here

을 확인 할 수 있습니다 중 하나를 수행 할 수 있습니다

(a)는 NullReferenceException이 제기 - 흐름을 깨고 돌아갑니다

RAWDATA 인 경우 (b)는 기본 값을 반환 null - 흐름을 중단 해, 디폴트 치를 돌려줍니다. 당신이 널 (null) 다음 널 (NULL) 데이터 타입에 갈 반환에 관심이 있다면

float f() 
    { 
     if (RawData == null) 
     { 
      throw new NullReferenceException(); 
      return default(float); 
     } 
     return doOtherOperation(RawData); 
    } 

    float doOtherOperation(PointF[] RawData) 
    { 
     //do what you wanted to do 
     return default(float); 
    } 
관련 문제