메소드가 false를 리턴하는지 확인 : 결과를 임시 변수에 지정하거나 메소드 호출을 조건부로 직접 넣습니까?


9

if 문에서 true 또는 false 값을 반환하는 메서드를 호출하는 것이 좋은 방법입니까?

이 같은:

private void VerifyAccount()
{
    if (!ValidateCredentials(txtUser.Text, txtPassword.Text))
    {
        MessageBox.Show("Invalid user name or password");
    }
}

private bool ValidateCredentials(string userName, string password)
{
    string existingPassword = GetUserPassword(userName);
    if (existingPassword == null)
        return false;

    var hasher = new Hasher { SaltSize = 16 };
    bool passwordsMatch = hasher.CompareStringToHash(password, existingPassword);

    return passwordsMatch;
}

또는 변수에 저장하고 다음과 같은 다른 값을 사용하여 비교하는 것이 좋습니다

bool validate = ValidateCredentials(txtUser.Text, txtPassword.Text);
if(validate == false){
    //Do something
}

.NET을 언급 할뿐만 아니라 모든 프로그래밍 언어의 질문을 언급하고 있으므로 .NET을 예로 사용했습니다.


3
임시 변수를 사용하는 경우 if (!validate)대신을 쓰십시오 if (validate == false).
Philip

12
함수의 이름을 "CredentialsAreValid ()"와 같이 지정하면 부울을 반환해야하지만 그렇지 않은 경우에는 좋은 방법입니다
Zachary K

3
IsValidCredentials문법적으로 어색하지만 부울 리턴 값을 표시하는 일반적인 형식입니다.
zzzzBov

@Philip if (! validate)와 this if (validate)의 차이점은 무엇입니까 ??
KyelJmD

!"NOT"연산자이며 부울 표현식을 무효화합니다. 그래서 if (!validate)반대입니다 if (validate). if 문이 validatetrue가 아닌 경우 입력됩니다 .
Philip

답변:


26

이 모든 것들과 마찬가지로 그것은 달려 있습니다.

호출 결과를 사용하지 않으려는 경우 ValidateCredentials결과를 로컬 변수에 저장할 필요가 없습니다 (디버깅 목적을 제외하고). 그러나 코드가 더 읽기 쉽고 (따라서 유지 관리가 용이 ​​한) 변수를 사용하면 코드를 읽을 수 있습니다.

코드의 효율성이 떨어질 수는 없습니다.


1
그 유형은 읽을 수 있습니까? 내가 위에서 한 것처럼
KyelJmD 2:26에

@KyelJmD : 프로그래밍하는 문화에 따라 다릅니다. 프로그래밍 한 장소 !ValidateCredentials에서는 코드에서 수행중인 작업을 명시 적으로 나타 내기 때문에 더 읽기 쉽습니다 . 매우 분명합니다. 호출하는 함수에 "자가 문서화"이름이 없으면 변수를 사용하는 것이 좋습니다. 그대로, 변수를 생략하고 자체 문서화 코드를 유지하는 것이 좋습니다.
Joel Etherton

ValidateCredentials는 처음부터 읽을 수 없습니다. 이름은 결과의 의미를 어떻게 알려줍니까? CredentialsAreValid 또는 CredentialsAreInvalid가 훨씬 좋습니다.
gnasher729

9

추가 변수를 사용하는 이유는 무엇입니까? 나는 첫 번째 접근 방식을 선호합니다. 더 읽기 쉽고 간단합니다.


4

if 문에서 true 또는 false 값을 반환하는 메서드를 호출하는 것이 좋은 방법입니까?

예, 조건이 인라인하기에 충분히 단순하지 않고 읽을 수있는 경우.

또는 변수에 저장하고 다음과 같은 다른 값을 사용하여 비교하는 것이 좋습니다

여러 곳에서 값을 사용하거나 코드를 더 읽기 쉽게 만들어야하는 경우에만이 작업을 수행해야합니다. 그렇지 않으면 변수에 대한 할당이 필요하지 않습니다. 불필요한 코드는 최상의 낭비이며 최악의 경우 결함의 원인입니다.


2

보자...

그것은 KISS 에 관한 것이기 때문에 변수없이 할 수있을 때 추가 변수를 만들 필요가 없습니다. 또한 필요가 없을 때 더 입력 할 필요가 없습니다.

그러나 DRY 때문에 나중에 전화를 걸고 ValidateCredentials직접 입력 ValidateCredentials(txtUser.Text, txtPassword.Text)하면 추가 변수를 만들어야한다는 것을 알 수 있습니다.


2

예, 일반적으로 조건과 같은 방법을 사용하는 것이 좋습니다. 메소드 이름이 메소드가 bool을 리턴 함을 표시하면 도움이됩니다. 예를 들어 CanValidateCredentials와 같습니다. C 스타일 언어에서이 메소드는 종종 Is 및 Can 접두사의 형식을 사용하며 Ruby에서는 '?' 접미사.


1
메소드 이름에 대해서는 좋은 점이지만 "if"로 메소드 이름을 시작하지는 않습니다. 그런 다음 코드는 "if if"를 읽습니다. "Can"은 괜찮습니다 : if (cat.canOpenCanOfCatFood()).
케빈 클라인

감사합니다, @Kevin. 나는 'If'가 아니라 'Is'를 의미했습니다. 나는 대답을 편집
기독교 Horsdal에게

1

아직 지적되지 않은 또 다른 우려가 있습니다 : 단락 평가 . 이 두 코드 조각의 차이점은 무엇입니까?

예 # 1 :

if(foo() && bar() && baz())
{
    quz();
}

예 # 2 :

bool isFoo = foo();
bool isBar = bar();
bool isBaz = baz();
if(isFoo && isBar && isBaz)
{
    quz();
}

이 두 코드 조각은 같은 것으로 보이지만, 언어가 단락 평가를 지원하는 경우이 두 조각은 다릅니다. 단락 평가는 코드가 조건을 통과하거나 실패하는 데 필요한 최소값을 평가 함을 의미합니다. 예제 # 1의 경우, foo ()가 false를 리턴하면 bar () 및 baz ()도 평가되지 않습니다. 이는 foo ()가 false를 리턴하거나 foo ()가 true를 리턴하고 bar ()가 false를 리턴하면 baz ()가 장기 실행 함수 호출 인 경우 건너 뛸 수 있으므로 유용합니다.

예제 # 2에서는 그렇지 않습니다. foo (), bar () 및 baz ()는 항상 평가됩니다. bar () 및 baz ()가 부작용을 나타낼 것으로 예상되면 Example # 1에 문제가 있습니다. 위의 예제 # 1은 실제로 다음과 같습니다.

예 # 3 :

if(foo())
{
    if(bar())
    {
        if(baz())
        {
            quz();
        }
    }
}

예제 # 1과 # 2 중에서 선택할 때 코드의 이러한 차이점에 유의하십시오.


1

가독성 문제에 대한 확장 ...

결과를 변수에 저장해야하는 두 가지 이유를 생각할 수 있습니다.

  1. 조건을 두 번 이상 사용하려는 경우 변수에 저장하면 함수를 한 번만 호출하면됩니다. (이것은 저장된 값이 여전히 유효하다고 가정합니다. 다시 테스트 해야하는 경우에는 적용되지 않습니다.)

  2. 변수에 저장하면 함수 호출에 표시되는 것보다 더 의미있는 이름을 조건에 부여하여 가독성을 향상시킵니다.

예를 들면 다음과 같습니다.

bool foo_is_ok = is_ok(foo);
if (foo_is_ok) ...

가독성에 도움이되지 않지만 다음과 같습니다.

bool done_processing = feof(file1) && feof(file2);
if (done_processing) ...

아마도 feof(file1) && feof(file2)우리가 처리를 완료 했음을 의미하는 것은 분명하지 않기 때문일 것입니다 .

문제의 passwordsMatch변수는 아마도 내 것보다 더 좋은 예일 것입니다.

일회용 변수는 어떤 값에 의미있는 이름을 주면 유용합니다. (이것은 물론 인간 독자의 이익을위한 것입니다.)


done_processing변수 를 도입하는 대신 주석을 삭제하려고 합니다. 결국, 이름 done_processing은 주석의 기능을합니다. 그리고 실제 의견을 통해이 조건이 처리를 완료 한 이유 에 대해 한두 단어를 말할 수 있습니다 . 아니 내가 좋은 주석을 해요 것을,하지만, 난 아마 ... 실제 코드에서 어느 쪽도 할 수없는 것
cmaster - 분석 재개 모니카

@ cmaster : 주석의 한 가지 문제는 코드와 쉽게 동기화되지 않을 수 있다는 것입니다. 명명 된 변수 done_processing는 의도를 표현하는보다 내구성있는 방법입니다.
Keith Thompson

포인트 번호 2의 경우 +1-때로는 이름이 잘 알려진 temp var가 실제로 상황을 명확하게합니다.
user949300
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.