2011-03-30 8 views
31

새로운 개념으로 놀고있는 동안 Ternary Operator을 발견했습니다. 잠시 그걸 가지고 노는 후, 나는 그 한계를 시험하기로 결정했다.3 진 연산자를 사용하는 메서드 호출

그러나 컴파일 할 때 특정 코드 행을 얻을 수 없을 때 빠르게 재밌어졌습니다.

Error 1 Only assignment, call, increment, decrement, and new object expressions can be used as a statement 
Error 2 Type of conditional expression cannot be determined because there is no implicit conversion between 'void' and 'void' 

내가 호출 할 방법을 결정하기 위해 Ternary Operator을 사용한 적이 없으며, 그것도 가능하면 알 수 있습니까 :

int a = 5; 
int b = 10; 
a == b ? doThis() : doThat() 

    private void doThis() 
    { 
     MessageBox.Show("Did this"); 
    } 
    private void doThat() 
    { 
     MessageBox.Show("Did that"); 
    } 

이 줄은 나에게 두 가지 오류를 제공합니다. 메서드 호출을위한 한 줄의 아이디어 인 If Else Statement을 좋아합니다.

나는 약간의 연구를했으며이 일을하는 사람의 예를 찾을 수 없으므로 제공 할 수없는 것을 기대할 수도 있습니다.

가능하다면 저의 잘못을 저에게 밝혀주십시오. 가능하지 않습니다. 다른 방법이 있습니까?

+1

doThis 및 doThat 함수가 int 유형의 값을 반환하는지 확인하십시오. – Chandu

+0

죄송합니다. 빠른 방법을 게시 해 드리겠습니다. –

+1

만약 한 줄로 된'If Else'를 정말로 원한다면, 그것을 한 줄로 작성하십시오 :'if (condition) doThis(); else doThat();'3 단계 연산자 (생각했던대로 작동하는 경우)는 짧아 지지만, 간결함은 항상 좋은 것은 아닙니다. –

답변

2

이유는 정말 유용하다 내 진정한 질문에 대답해라.

좀 더 놀아 본 후에,이 연산자를 사용하여 위의 명령문을 사용할 수 있다고 생각했지만 코드가 잘못되었습니다.

위 문장을 다음과 같이 변경해야합니다.

int a = 5; 
int b = 10; 
int result = a == b ? doThis() : doThat(); 

private int doThis() 
{ 
    MessageBox.Show("Did this"); 
    return 0; 
} 
private int doThat() 
{ 
    MessageBox.Show("Did that"); 
    return 1; 
} 

이 코드는 컴파일해야하며 실행해야합니다. 그러나 이러한 메서드가 원래 아무것도 반환하지 않고 코드의 다른 영역을 참조한 경우 이러한 메서드를 호출 할 때마다 반환 개체를 처리해야합니다.

그렇지 않으면 한 줄의 메서드 선택기에 대해 삼항 연산자를 사용할 수 있으며 결과를 사용하여 다음 줄에서 호출 한 메서드를 알 수 있습니다.

int result = a == b ? doThis() : doThat(); 

if (result == 0) 
    MessageBox.Show("You called doThis()!"); 

지금,이 코드는 절대적으로 무의미하고 쉽게 그 밖에하면 수행 할 수 있지만, 난 그냥 그것을 할 수 있는지 알고 싶어하고 당신이 그것을 작동하도록하기 위해 수행했다.

이제 이러한 메서드에서 모든 형식을 효과적으로 반환 할 수 있다는 것을 알았으므로이 방법이 조금 더 유용 할 수 있습니다. 그것은 "나쁜 코딩 실습 (bad coding practice)"으로 간주 될 수 있지만 절대로 그것이 결코 의미가없는 상황에서 매우 유용 할 수 있습니다.

어떤 조건을 기반으로 하나의 객체 또는 다른 객체에 액세스 할 수 있으며 이는 한 줄의 코드에서 유용 할 수 있습니다.

UserPrivileges result = user.Group == Group.Admin ? GiveAdminPrivileges() : GiveUserPrivileges(); 

private UserPrivileges GiveAdminPrivileges() 
{ 
     //Enter code here 
     return var; 
} 
private UserPrivileges GiveUserPrivileges() 
{ 
     //Enter code here 
     return var; 
} 

물론,이 IF 문하여 수행 할 수 있습니다,하지만 난 다른 용도의 삼항 연산자를 사용하여 프로그래밍의 재미를 만드는 것이라고 생각합니다. 이제는 If Else 문과 같이 효율적이지 않을 수도 있습니다.이 경우에는 절대로 사용하지 않을 것입니다.

+4

** 실제로 ** 그렇게 할 필요가 없습니다. – SLaks

+0

동의하지만, 완전성을 위해 bool, string 또는 모든 객체를 반환 할 수도 있습니다. 그러나 실제로, 진술 1은 무엇입니까? 정말 컴파일러를 의미합니까? 별로 좋지는 않지만 훌륭한 코딩 방법을 익히는 데 도움이되지 않습니다. – Michael

+0

@Michael 저는 그것을 몰랐고, 이것이 제 질문의 요점입니다. 나는 이것이 이것을 작동시키는 법과 그것을 사용함으로써 얻게되는 이익/결과를 알고 싶었다. 반환 유형을 선택하는 기능을 사용하면 더욱 유용합니다. –

15

삼항 연산자는 무언가를 반환해야합니다. 일반적인 사용은 다음과 같이이다 :

int x = (a > b) ? a : b; 

당신이 컴파일러는 불평

a + b; 

같은 것을 시도하십시오. 자신에 대한 합법적 인 진술하지 않습니다 - "A B"- "B a"또는

(a > b) ? a - b : b - a; 

는 기본적으로 하나의 바로 가기입니다.

+5

+1. 만약 DoThis()와 DoThat()이 어떤 것을 반환했다면, 3 진을 사용하여 실행을 제어하고 일부 지역 변수에 결과를 할당 할 수 있습니다. 그러나 이는 3 항 연산자의 의도가 아닙니다. 다른 개발자들은 부작용보다는 반환 가치가 더 중요하다고 생각할 것입니다. 기본 if 문을 사용하십시오. 당신의 의도는 명확하게 유지 될 것입니다 (그리고 당신은 당신의 방법 서명을 그냥 영리하게 만들 필요가 없습니다). – KeithS

+4

+1 또 다른 요점은 삼항 연산자에서 반환 될 수있는 두 값이 같은 유형이거나 암시 적으로 같은 유형으로 변환 가능해야한다는 것입니다. –

31

세 번째 연산자는 값을 반환하는 데 사용되며 해당 값을 할당해야합니다. doThis()doThat() 값을 반환한다고 가정하면 간단한 할당으로 문제가 해결됩니다.

시도하고있는 것을 원한다면 가능하지만 해결책은 예쁘지 않습니다.

int a = 5; 
int b = 10; 
(a == b ? (Action)doThis : doThat)(); 

다음은 괄호로 호출되는 동작 대리자를 반환합니다. 이를 달성하는 일반적인 방법은 아닙니다.

+1

사실, 일을하는 올바른 방법이 아닙니다. 하지만 질문에 대한 가장 정확한 답 : OP는 삼항 연산자를 사용하여 호출 할 메서드를 선택하기를 원했습니다. 정확히 코드 조각이 무엇입니까? –

+0

이것이 "정확하지 않은 이유는 무엇입니까?" 또 다른 포스터는 지금까지 바보라고 불렀습니다. – Morgoth

+0

대답은 실질적으로 느리다는 것입니다. http://www.dotnetperls.com/action – Morgoth

1

조건부 연산자는 값을 반환하는 식입니다.
void을 반환하는 함수와 함께 사용할 수 없습니다.

대신 if을 사용해야합니다.

+0

에서 훌륭합니다. 그러나 OP는 사용자가 다음과 같은 조건부 연산자를 사용할 수 있다고 가정하고있었습니다. C/C++ 스타일 구문.이 구문을 사용하면 조건부 동작 내에서 메서드를 호출 할 수 있습니다. 그러나 나는 OP가 말했던 것에서 C/C++ 구문의 조건 연산자를 사용하지 않았다고 가정합니다. – Jake

1

.NET은 이유 때문에이 (읽기 쉬운 버전)을 (쉽게) 지원하지 않습니다. 그것은 매우 jankity하고 코드를 읽기가 어렵게 만듭니다. 논리 트리는 비교적 쉽게 트래버스해야합니다. 내가 일자리와 모든 코드에 들어가기 위해서 그들은 값을 할당하고 메서드를 호출하는 데 3 진을 사용했다. 나는 그냥 떠날 것이라고 생각한다.

+0

여전히 과제가 필요합니다. – NerdFury

+0

이것이 코드를 읽기 어렵게 만드는 유일한 방법은 설명이없는 변수 이름과 마법 번호 (의미가없는 것 같은 숫자)를 사용하는 경우입니다. 삼항 연산자가 올바르게 사용되면 If/Else처럼 쉽게 읽혀집니다. –

+0

메소드 이름은 길고 매개 변수가 자주 포함될 수 있습니다. 한 메서드 호출이 시작되고 다른 끝이 끝나는 곳을 알아 내기 위해 200 자로 된 줄을 읽지 않아도됩니다. 여러 줄 (적어도 나를 위해)은 일반적으로 읽기가 쉽고 거의 여러 줄의 줄이 필요하지 않습니다. 비교 대상 :'(VicePresidentsAttendee.AnnualSalary == MoneyHelper.MonetizeInt (SalaryThreshold))? RaiseHelper.AddABillionDollarBonus (VicePresidentAttendee.PersonId) : RaiseHelper.RegisterPersonForYearlyRaise (SalaryThreshold, PersonId, SickDaysLastQuarter, TypingSpeedInGoalWordsPerMinute, LunarPhaseOnLastPiDay); – FreeAsInBeer

2

당신은하지만,이 작업을 수행 할 수 있어야한다 :

 int a = 5; 
     int b = 10; 

     var func = a == b ? (Action)doThis : (Action)doThat; // decide which method 

     func(); // call it 

하지 않는 것이 위의 문이 작품은 다른 사용자에 의해 제공되었다되지 효과적으로하지 않았다 않는 이유

7

당신이 정말로 조건부 연산자 void 메소드를 호출 할 경우 위임을 사용할 수 있습니다

(something ? new Action(DoThis) : DoThat)(); 

을 방법은 매개 변수를 사용하는 경우이 더 복잡하게 될 것이다.
람다 식을 조건부에 넣거나 Action<T>을 사용할 수 있습니다.

그러나 이것은 매우 어리석은 일입니다.