[C#] if / else, 좋은 디자인


Answers

내가 코딩 할 내용은 다음과 같습니다.

return obj.CanDo(type) ? Do(obj) : false;
Question

이 함수를 단순화하는 것은 수용 가능 / 좋은 스타일인가?

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }
    else
    {
        return false;
    }
}

같이:

bool TryDo(Class1 obj, SomeEnum type)
{
    return obj.CanDo(type) && Do(obj);
}

두 번째 버전은 짧지 만 틀림없이 덜 직관적입니다.




조건부 표현식에서 하위 표현식 평가의 순서를 이용하는 팬이 아니기 때문에 두 번째 버전을 좋아하지 않습니다. 그것은 나의 마음 속에있는 하위 표현에 기대되는 순서를 두어 우선 순위가 같아야한다.

동시에, 나는 첫 번째 버전이 조금 비대해진 것을 알았으므로, 내가 읽을 수 있다고 생각하는 삼항 솔루션을 선택할 것입니다.




내 생각에 Class1 Type은 SomeEnum 값이 주어지면 할 수 있는지를 결정해야한다고 생각한다.

결정을위한 입력을 처리 할 수 ​​있는지 여부에 대한 결정을 내릴 것입니다.

bool TryDo(Class1 obj, SomeEnum type)
{
    return obj.Do(type));    
}



그러지 마. 간단하고 직관적으로 유지하십시오.




조금 더 쉽게 읽을 수있는 또 다른 방법은 조건부 연산자를 사용하는 것입니다.

bool TryDo(Class1 obj, SomeEnum type) {
  return obj.CanDo(type) ? Do(obj) : false;
}



유능한 프로그래머를위한 두 번째 코드가 무엇인지는 분명하지만,보다 일반적인 경우에는 "전제 조건이 충족되면 행동을 취하고 그렇지 않으면 실패"와 같은 코드를 작성하는 것이 더 명확하고 쉽게 이해할 수 있습니다.

이것은 다음 중 한 가지 방법으로 달성 할 수 있습니다.

return obj.CanDo(type)? Do(obj) : false;

또는,

if(obj.CanDo(type)) return Do(obj);
return false;

이 같은 스타일은 반환 유형에 관계없이 복제 될 수 있기 때문에이 우수한 점이 있습니다. 예를 들어,

return (array.Length > 1)? array[0] : null;

또는,

return (curActivity != null)? curActivity.Operate() : 0;

같은 스타일을 반환 값이없는 상황으로 확장 할 수도 있습니다.

if(curSelection != null)
    curSelection.DoSomething();

내 두 센트.




else 는 쓸모가 없지만 && 는 순수 텍스트만큼 읽기 쉽지 않습니다.

나는 다음을 선호한다 :

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }   
    return false;
}



첫 번째 버전은 오해의 가능성을 줄여 읽고 이해하기 쉽습니다. 실제 코드에서는 이것이 중요하다고 생각합니다.




대괄호가있는 버전 :

bool TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
    {
        return Do(obj);
    }

    return false;
}

또는 괄호가없는 버전 (답변에 대한 논평에서 이에 대한 논쟁이 큽니다.) :

bool TryDo(Class1 obj, SomeEnum type)
{
    /*
     * If you want use this syntax of
     * "if", this doing this on self
     * responsibility, and i don't want
     * get down votes for this syntax,
     * because if I remove this from my
     * answer, i get down votes because many
     * peoples think brackets i wrong.
     * See comments for more information.
     */
    if (obj.CanDo(type))
        return Do(obj);

    return false;
}

첫 번째 코드 예제가 더 좋지만 내 버전이 더 좋다고 생각합니다.

두 번째 버전은 읽기 쉽지 않으며 코드를 유지 관리하기가 어렵습니다 .




예.

특히 CanDoSomethingDoSomething 과 같은 이름을 사용하면 유능한 프로그래머는 두 번째 코드에서 "조건이 충족 되는 경우에만 무언가를 수행하고 결과를 반환하십시오"라는 사실을 절대적으로 분명히 알 수 있습니다. "if와 only if"는 단락 된 && 연산자의 핵심 의미입니다.

첫 번째 코드는 두 번째 코드보다 더 많은 정보를 제공하지 않고 복잡하고 길게 길다.

그러나 일반적으로 두 가지 조건은 ( CanDoDo 에서와 같이) 친밀한 관계를 형성 Do 않을 수 있으며, 같은 조건에 두는 것이 직관적이지 못할 수도 있기 때문에 논리적으로 분리하는 것이 더 나을 수도 있습니다.

많은 사람들은 첫 번째 버전이 훨씬 더 명확하다고 주장합니다. 나는 그들의 주장을 정말로 듣고 싶다. 나는 어떤 것도 생각할 수 없다.

다른 한편으로는,이 밀접하게 관련된 코드가 있습니다.

if (condition)
    return true;
else
    return false;

이것은 항상 다음과 같이 변형되어야합니다 :

return condition;

예외는 없습니다 . 언어에 능숙한 사람에게는 간결하면서도 더 읽기 쉽습니다.




이 경우 첫 번째 옵션을 사용합니다. 훨씬 더 읽기 쉽고 코드의 의도가 훨씬 명확합니다.




일부 사람들이 언급하는 부작용 문제는 가짜입니다. "Do"라는 메소드가 부작용이 있다는 사실에 놀란 사람은 없을 것이다.

사실, 두 가지 방법을 호출합니다. 이 두 메소드 모두 bool을 반환 값으로 사용합니다. 두 번째 옵션은 매우 명확하고 간결합니다. (비록 내가 바깥 쪽 괄호를 없애고 끝나는 세미콜론을 잊어 버렸지 만).




이미 몇 가지 좋은 해답이 있지만, 나는 (내가 생각할 때) 좋은, 읽을 수있는 코드의 또 하나의 예를 보여줄 것이라고 생각했다.

bool TryDo(Class1 obj, SomeEnum type)
{
    bool result = false;

    if (obj.CanDo(type))
    {
        result = Do(obj);
    }

    return result;
}

취향에 따라 if 문 본문을 중심으로 중괄호를 유지하거나 제거합니다.

이 방법은 뭔가 다른 일이 발생하지 않으면 결과가 false 라는 것을 보여주기 때문에 Do() 가 무언가를하고 TryDo() 가 반환 값으로 사용하는 부울 값을 반환한다는 것을보다 명확하게 보여줍니다.




단축 버전은 Do가 무언가를한다는 사실을 숨 깁니다. 비교를 수행하고 결과를 반환하는 것처럼 보이지만 실제로 비교를 수행하고 작업을 수행하는 것처럼 보입니다. 코드에이 "부작용"이 있는지 분명하지 않습니다.

문제의 핵심은 평가 결과와 조치의 리턴 코드를 반환한다는 것입니다. 이 방법으로 두 가지 평가 결과를 반환했다면 문제가 없습니다.




두 번째 기능에 부작용이 없다면 IMO는 정상입니다. 하지만 Do ()에는 부작용이 있기 때문에 if와 함께 갈 것입니다.

나의 지침은 표현에 부작용이 없어야한다는 것입니다. 부작용이있는 함수를 호출 할 때는 명령문을 사용하십시오.
이 지침은 함수가 실패 코드를 반환하는 경우 문제가 있습니다. 이 경우 해당 오류 코드를 변수에 할당하거나 직접 반환합니다. 하지만 복잡한 표현식에서는 반환 값을 사용하지 않습니다. 아마 표현식에서 가장 외적인 함수 호출 만 부작용을 가져야한다고 말할 수 있습니다.

더 자세한 설명은 Eric Lippert의 블로그 를 참조하십시오.




나에게는 두 번째 방법을 선호한다. bool을 반환하는 대부분의 메소드는 단순한 조건부 논리가 포함될 때 같은 방식으로 단축됩니다.




아니, 두 번째 버전

return (obj.CanDo(type) && Do(obj))

프로그램 흐름을 제어하는 ​​방법이 아니라 최적화 인 && 연산자의 단락 동작에 의존합니다. 내 생각에 이것은 프로그램 흐름에 예외를 사용하는 것 (그리고 거의 나쁜 것)과 약간 다릅니다.

나는 영리한 코드가 싫어, 이해하고 디버그하는 암캐 야. 함수의 목적은 "우리가 이것을 할 수 있다면, 그것을 수행하고 그 결과를 돌려 주면 거짓을 돌려 준다"이다. 원래 코드는 그 의미를 매우 분명하게 만듭니다.




나는 이것에 대해 싫어할 지 모르지만 무엇에 관해서 :

if (obj.CanDo(type)) return Do(obj);
return false;

하나의 강선에 괄호를 쓰는 것을 좋아하지 않습니다.




나는이 디자인이 맘에 들지 않으며 명백한 이유가 아닐 수도있다. 나를 귀찮게하는 것이있다. return Do (obj); 나에게 그것은 Do 함수가 bool 리턴 타입을 갖는 것은 이해가되지 않는다. 이 속성을 밀어 넣는 오류에 대한 대용품입니까? 대부분의 경우이 함수는 void이거나 복잡한 객체를 반환해야합니다. 시나리오는 단순히 나타나지 않아야합니다. 또한 부울이 어떻게 든 지금은 이해가된다면, 그것은 쉽게 미래에 의미를 만드는 것을 멈출 수 있습니다. 코드를 변경하면 더 많은 수정 작업이 필요합니다.




TryDo가 False를 반환 할 때도 'CanDo가 아닌'또는 'False가 반환되었습니다'때문인지 여부를 판단 할 수 없습니다.

결과를 무시할 수 있다는 것을 충분히 이해하지만 결과가 의미가 있다는 것을 의미합니다.

결과가 무의미한 경우 의도는

void TryDo(Class1 obj, SomeEnum type)
{
    if (obj.CanDo(type))
        Do(obj);
    return;
}

결과에 의미가있는 경우 두 가지 '거짓'결과를 구별 할 수있는 방법이 있어야합니다. IE 'If (! TryDo (x))'의 의미는 무엇입니까?

편집 : 다른 말로하면, OP의 코드는 '나는 수영 할 수 없다'는 말은 '나는 수영하고 익사하려고했습니다'