[c#] 함수가 null 또는 빈 객체를 반환해야합니까?

함수에서 데이터를 반환 할 때 가장 좋은 방법 은 무엇입니까? Null 또는 빈 객체를 반환하는 것이 더 낫습니까? 그리고 왜 하나는 다른 하나를해야합니까?

이걸 고려하세요:

public UserEntity GetUserById(Guid userId)
{
     //Imagine some code here to access database.....

     //Check if data was returned and return a null if none found
     if (!DataExists)
        return null; 
        //Should I be doing this here instead? 
        //return new UserEntity();  
     else
        return existingUserEntity;
}

이 프로그램에는 해당 GUID가있는 데이터베이스에 사용자 정보가없는 유효한 사례가 있다고 가정합니다. 이 경우 예외를 던지는 것이 적절하지 않다고 생각할까요? 또한 예외 처리로 인해 성능이 저하 될 수 있다는 인상을 받고 있습니다.



답변

사용 가능한 데이터가 없음을 나타내려는 경우 일반적으로 null을 반환하는 것이 가장 좋습니다.

빈 객체는 데이터가 반환되었음을 나타내며 null을 반환하면 아무것도 반환되지 않았 음을 나타냅니다.

또한 null을 반환하면 객체의 멤버에 액세스하려고하면 null 예외가 발생하여 버그가있는 코드를 강조 표시하는 데 유용 할 수 있습니다. 빈 개체의 멤버에 액세스해도 버그가 발견되지 않을 수 있습니다.


답변

귀하의 사례에 가장 적합한 것이 무엇인지에 달려 있습니다.

“이러한 사용자가 존재하지 않습니다”와 같이 null을 반환하는 것이 합리적입니까?

아니면 기본 사용자를 만드는 것이 합리적입니까? 이것은 사용자가 존재하지 않는 경우 호출 코드는 사용자가 요청할 때 존재하기를 원한다고 안전하게 가정 할 수있을 때 가장 의미가 있습니다.

또는 호출 코드가 잘못된 ID를 가진 사용자를 요구하는 경우 예외 ( “FileNotFound”)를 발생시키는 것이 합리적입니까?

그러나 우려 / SRP 관점의 분리에서 처음 두 가지가 더 정확합니다. 그리고 기술적으로 첫 번째는 가장 올바른 (하지만 머리로) – 사용자를 얻기 – GetUserById는 단 한 가지에 대한 책임을 져야한다. 다른 것을 반환하여 자체 “사용자가 존재하지 않음”사례를 처리하면 SRP를 위반할 수 있습니다. 다른 검사로 분리- bool DoesUserExist(id)예외를 던지도록 선택한 경우 적절합니다.

아래의 광범위한 의견을 바탕으로 : API 수준의 디자인 질문 인 경우이 방법은 “OpenFile”또는 “ReadEntireFile”과 유사 할 수 있습니다. 우리는 일부 저장소에서 사용자를 “열고”결과 데이터에서 개체를 수화하고 있습니다. 이 경우 예외 적절할 수 있습니다 . 아닐 수도 있지만 가능할 수도 있습니다.

모든 접근 방식이 허용됩니다. API / 응용 프로그램의 더 큰 컨텍스트에 따라 다릅니다.


답변

개인적으로 NULL을 사용합니다. 반환 할 데이터가 없다는 것이 분명합니다. 그러나 Null 개체 가 유용한 경우 가 있습니다.


답변

반환 유형이 배열이면 빈 배열을 반환하고 그렇지 않으면 null을 반환합니다.


답변

특정 계약이 위반 된 경우 예외를 처리해야합니다.
특정 예에서 알려진 ID를 기반으로 UserEntity를 요청하면 누락 된 (삭제 된) 사용자가 예상되는 경우에 따라 다릅니다. 그렇다면 반환 null하지만 예상되는 경우가 아니면 예외를 throw하십시오.
함수가 호출 UserEntity GetUserByName(string name)되면 아마도 throw되지 않고 null을 반환합니다. 두 경우 모두 빈 UserEntity를 반환하면 도움이되지 않습니다.

문자열, 배열 및 컬렉션의 경우 일반적으로 상황이 다릅니다. 메서드가 null‘빈’목록으로 수락해야 하지만 길이가 0이 아닌 컬렉션을 반환 해야한다는 MS 지침 양식을 기억합니다 null. 문자열도 마찬가지입니다. 빈 배열을 선언 할 수 있습니다.int[] arr = new int[0];


답변

이것은 특정 Guid Id를 가진 사용자의 존재가이 기능의 정상적인 사용 사례인지 또는이 방법이 사용자에게 제공하는 기능을 응용 프로그램이 성공적으로 완료하지 못하게하는 이상 여부에 따라 비즈니스 질문입니다. 반대하다 …

“예외”인 경우 해당 ID를 가진 사용자가 없으면 응용 프로그램이 수행하는 모든 기능을 성공적으로 완료하지 못할 수 있습니다 (우리는 제품을 배송 한 고객에 대한 송장을 만드는 중입니다 … )이 경우 ArgumentException (또는 다른 사용자 정의 예외)이 발생합니다.

누락 된 사용자가 정상인 경우 (이 함수를 호출했을 때 발생할 수있는 정상적인 결과 중 하나) null을 반환합니다.

편집 : (다른 답변에서 Adam의 의견을 다루기 위해)

응용 프로그램에 여러 비즈니스 프로세스가 포함 된 경우 (하나 이상이 성공적으로 완료하기 위해 사용자를 필요로하고, 하나 이상이 사용자없이 성공적으로 완료 될 수있는 경우) 예외는 호출 스택에서 더 멀리 던져야합니다. 사용자를 필요로하는 비즈니스 프로세스는이 실행 스레드를 호출합니다. 이 메소드와 그 시점 (예외가 발생하는 곳) 사이의 메소드는 사용자가 존재하지 않는다는 것을 전달해야합니다 (null, boolean 등-구현 세부 사항 임).

그러나 응용 프로그램 내의 모든 프로세스 에 사용자가 필요한 경우이 방법에서 여전히 예외가 발생합니다 …


답변

개인적으로 null을 반환합니다. DAL / 리포지토리 레이어가 작동하는 방식이기 때문입니다.

존재하지 않으면 성공적으로 객체를 가져 오는 것으로 해석 될 수있는 것을 반환하지 마십시오 null. 여기서 아름답게 작동합니다.

가장 중요한 것은 DAL / Repos Layer 전체에 일관성을 유지하는 것인데, DAL / Repos Layer를 사용하는 방법에 혼란을주지 않습니다.