'var'과 null 병합 연산자 '??'는 얼마나 멀리 있어야합니까? 가독성을 저해하지 않으면 서 즐겁게 지낼 수 있습니까?


23

나는 질문의 제목이 매우 주관적이라는 것을 알고 있지만 ??동료 들이 운영자 를 사용하는 것에 직면했다 var.

??연산자 를 사용하기 위해 주어진 주장 은 코드의 가독성을 없애줍니다.

내 질문은, 사용을 시작할 때 같은 일이 발생하지 var않습니까?


49
설명 된 후 "개발자"??널 병합 연산자를 이해할 수없는 경우 프로덕션 코드 근처에서 허용되지 않아야합니다.
CaffGeek

12
우리는 연산자를 IfNullThen에. ? IfSoChoose 일 수 있습니다. :는 ElseChoose입니다. +는 추가입니다. -단항이 아닌 한 빼기는 빼기입니다. -DecrementBeforeUsing과 DecrementAfterUsing 사이에 분할됩니다. C ++에서는 매크로를 사용하여이 작업을 수행 할 수 있습니다.
Lee Louviere

7
@ Xaade : 아이러니 아닌가? ... 권리? ... 신은 그것이 아이러니하게 놔두었다.
Steven Jeuris

10
그것은 수 있습니다 @StevenJeuris 풍자 , 그러나 아니다 아이러니 .
커크 브로드 허스트

1
@ KirkBroadhurst : 나는 정정되었습니다 . 항상 그 두 가지를 혼동했습니다.
Steven Jeuris

답변:


53

Null 통합 연산자 (??)

개인적으로이 연산자를 사용하는 데 따른 단점은 없습니다. 'easy'에서 'complex'새로운 연산자에 이르기까지 다음 세 가지 코드 샘플을 고려하십시오.

마법없이 :

bool isNameSet = false;
string name;
if ( isNameSet )
{
    Console.WriteLine( name );
}
else
{
    Console.WriteLine( "No name set." );
}

삼항 연산자 :

bool isNameSet = false;
string name;
Console.WriteLine( isNameSet ? name : "No name set." );

Null 통합 :

string name = null;
Console.WriteLine( name ?? "No name set." );

이 연산자가 발명 된 이유는 매우 일반적인 프로그래밍 작업 을 나타 내기 때문 입니다. 당신이 그들에게 익숙하지 않기 때문에 그것들을 사용하고 싶지 않은 것은 단지 고집이납니다 . 언어는 진화하고, 기능은 진화하고, 사용하는 법을 배웁니다!

var 키워드

var 키워드에 대해 약간 다른 의견이 있습니다. 변수의 유형은 종종 코드에 대한 추가 정보를 제공합니다. var 키워드를 사용하여 유형을 숨기면 때로는 코드를 읽을 수 없게됩니다. 자동 완성 기능을 사용하지 않거나 식별자 위에 마우스를 올리면 실제로 무엇을 볼지 기대할 수 있습니다. 제 생각에는 코드 작성 속도가 느립니다.

유형에 추가 정보가 많이 없다는 것을 알면 키워드를 사용합니다.

  • 주로 foreach 루프 에서 설정이며 Resharper에서 배웠습니다. 대부분의 경우 탐색하는 컬렉션 유형을 알고 있으므로 해당 컬렉션 내에서 항목을 기대하고 있음을 알 수 있습니다.
  • Linq 쿼리 . linq 쿼리의 결과는 종종 매우 복잡한 제네릭 형식입니다. 이 유형을 표시하면 좋은 것보다 더 해 롭습니다.
  • 생성자로 간단히 초기화되는 긴 유형 이름. 생성자를 보면 유형이 무엇인지 이미 알 수 있습니다.

마지막 진술의 예 :

ThisIsSomeSpecializedTypeRightHere duplication =
    new ThisIsSomeSpecializedTypeRightHere();
var justAsReadable =
    new ThisIsSomeSpecializedTypeRightHere();  // Less duplication.

// But I still prefer the following ...
int number = 9;
SomeCreatedType foo = Factory.CreateSomeType();

24
마지막 예는 var 키워드가 뛰어날 때입니다. 코드 전체에 코드가 흩어져 있다고 상상해보십시오. Factory.CreateSomeType을 반환합니다 IEnumerable<SomeType>. 어느 날, 어떤 이유로 든 return으로 변경됩니다 SomeType[]. var를 사용했다면 재 컴파일 일뿐입니다.
pdr

1
그 예를 잘못 찾아서 음식을 찾으러 갔다. 멍청이! 더 좋은 예는 당신을 사용하는 것입니다. 어떤 경우 Factory.CreateSomeType()변경은을 반환 ISomeType?
pdr

4
@ pdr : 인터페이스가 변경되었으며 동작을 조정 / 추가해야 함을 의미합니다. 이름이 간단한 경우 물론 이름을 자동으로 바꿨습니다. '계약'이 변경되면 코드가 깨지는 것을 볼 수 있으므로 조정해야하는지 여부를 확인할 수 있습니다.
Steven Jeuris

2
콘크리트 유형을 반환하면 인터페이스가 반환되면 인터페이스가 동일한 다른 콘크리트 유형 (공장 패턴과 일치)을 허용하는 것보다 훨씬 가능성이 높습니다. 그러나 계약이 변경되면 코드가 깨질 것입니다.하지만 어디에서나 중요하지 않은 몇 가지 경우에만 깨질 수 있습니다.
pdr

1
@Tom Hawtin, 우리는 null완전히 피하는 것이 불가피하다는 것을 알고 있습니다. 또한 대안을 많이 찾을 null수록 null때로는 가장 깨끗한 솔루션을 사용한다는 것을 깨닫게됩니다 . 내 예제는 그다지 나쁜 IMHO가 아니며 nullable 유형의 적절한 사용법을 찾았습니다.
Steven Jeuris

16

var는 덜 상세한 코드를 허용하므로 가독성이 향상됩니다. 내 의견으로는, 가독성은 얼마나 많은 세부 사항이 표시되는지가 아니라 언뜻보기에 숨겨지는 세부 사항 수로 측정되어야합니다. Linq 예제 외에도 var는 다음 예제에서 소스 코드 수준에서 오리 타이핑을 허용합니다.

...
foreach (var message in messages) {
  var label = Factory.CreateLabel();
  label.Text = message;
  Controls.Add(label);
}
...

Text 속성을 제공하는 한 누가 레이블 유형을 신경 쓰나요?


이것이 winforms 레이블인지 아니면 WPF 레이블인지 이해하려고하는 사람.
Steven Jeuris

14
@Steven Jeuris : 일반적으로 알려진 컨텍스트 정보입니다. 그렇지 않으면 코드에 잘못된 방식으로 접근하고있는 것입니다.
Codism

기본 WPF 레이블인지 아니면 사용자 지정 레이블인지 알고 싶은 사람이 있습니까? :)
Steven Jeuris

14
1. Text 속성이있는 레이블이라면 그 사람이 정말로 관심을 가져야합니까? 2. 이것이 드물게 치료해야 할 이유가있는 경우 Intellisense에 문의하십시오. 3. Intellisense가없는 IDE에서 코드를 편집하는 경우 아마도 'var'보다 큰 불편을
겪을 것입니다.

4
추상화가 열악한 사람.
짐 발터

16

나는 그런 ??연산자를 가진 언어를 많이 사용하지 않았기 때문에 연산자 에 대해 진지하게 언급하지 않았습니다 . 에 관해서는 var, 사람들은 Ruby, Python, Perl 및 PHP와 같은 언어로 항상 완전하게 타이핑하는 프로그램을 프로그램합니다. 이러한 언어의 원주민은 공식적인 변수 유형이 일반적으로 관련없는 노이즈라는 것을 알고 있습니다. 당신은 변수 수 있는지에 더 관심이있어 즉, 구조적 / 오리 인터페이스.

마찬가지로, 나는 주로 D로 프로그래밍합니다. D는 정적으로 입력되었지만 auto키워드 는와 동일합니다 var. 독자에게 (암시 적 변환을 통해) 무언가의 유형을 강조 할 필요가없는 한 어디에서나 그것을 사용하는 것은 관용적 인 것으로 간주됩니다. 함수 반환 유형 (D에서 허용됨)으로 사용되는 경우를 제외하고는 프로그래밍 할 때 공식 / 명목 유형이 아닌 구조적 / 덕크 인터페이스의 관점에서 주로 생각하기 때문에 가독성을 방해하는 것으로 결코 발견하지 못했습니다.

또한 var가능한 모든 곳 에서 IMHO를 사용 하는 것이 DRY의 좋은 예입니다. 무언가의 유형은 한 곳에서만 지정해야 하며 전파해야 할 때마다 자동 으로 전파됩니다. 당신이 사용하는 경우 var와 어떤 점에서 변화에 변수 요구의 형식 유형, 필요한 변경이 자동으로 프로그램만큼 컴파일러에 의해 모든 곳에서 필요 전파됩니다 입력-올바른 아니라 프로그래머보다 수동으로 모든 인스턴스를 변경하지 여전히 . 이것은 Good Thing (TM)입니다.


13

나는 이것이 결국 팀에 대한 질문이라고 생각합니다. 내 팀의 다른 사람이 읽을 수없는 경우 예제를 사용하여 설득하기 위해 몇 번 시도하거나 더 읽기 쉬운 항문 약어 (예 : + =)를 지적하여 사용하지는 않지만 사용하지는 않습니다.

그러나 혼자 일하면 찾을 수 있습니까 ?? var는 제한없이 읽을 수 있습니다. 조차

var a = b ?? c ?? d ?? e ?? "";

나에게 분명하다.

삼항 연산자 dynamic는 물론 다른 문제입니다.


4
여기서는 'String.Empty'를 사용합니다.
Job

1
@Job, 정직하게, 나도 그렇게 할 것입니다. 나는 그 줄에 무언가를 넣은 다음 아무것도 생각하지 못했습니다 :)
pdr

4
var a = b ?? c ?? d ?? e ?? String.Empty ?? "";
Lee

2
@Xaade 당신은 충분히 확신 할 수 없습니다. 그러나 실제로 String.Empty 또는 ""를 사용하는 것이 개인적인 취향입니다. ""가 더 짧기 때문에 ""를 사용합니다.
Carra

12
@Xaade- String.Empty가 반환 null되면 깨진 코드가 많이 생깁니다 .
제시 C. 슬라이서

10

??를 사용하기 위해 주어진 인수 연산자는 코드의 가독성을 없애줍니다.

간단히 말해서,이 의견은 의견을 말한 사람에게 나에게 의견을 말하고 이해하지 못합니다. 특정 상황에서는 대부분의 경우에 해당 될 수 있지만 C # 팀이 "가독성"으로 인해 추가하기에 충분히 중요하다고 생각한 것을 할인하지는 않습니다. 나는 이것을 같은 카테고리 if(boolean_object)vs 에 넣었다 if(boolean_object == true). 어떤 사람들은 두 번째가 더 읽기 쉽다고 주장하지만 실제로는 누군가가 읽거나 타이핑 할 수 있도록 여분의 코드를 추가하고 일부 상황에서는 더 혼란 스러울 수 있습니다 (생각합니다 if(boolean_object != false))

내 질문은, var 사용을 시작할 때 같은 일이 발생하지 않습니까?

C # 팀은 당신이 무엇을할지 알고있는 것을 정의하지 못하게했습니다. 변수가 무엇인지 정의해야 할 필요가 없다면 (반환하는 객체가 x 유형이거나 실제로 읽을 수없는 것이 절대적으로 중요합니다), 나는을 사용 var합니다. var x = "MY_STRING";나는 그것이 그것을 본 문자열이라는 것을 안다. 사실, 나는 그것이 내가해야 할 일을하는 한 문자열이라는 것을 정말로 신경 쓰지 않습니다. 변수 유형을 정의하는 것은 컴파일러가 아닌 이점입니다. 뭔가 잘못되면 컴파일러는 변수 유형이 잘못된 경우 실행될 때 알려줍니다.


0

var생각에는 이 키워드는 원래 소개 된 상황 인 LINQ 쿼리에서 가장 잘 사용됩니다. 이 쿼리에서 반환 된 결과의 유형은 종종 사전에 결정하기 어려운 복잡한 이름을 가지고 있으며 독자가 코드의 기능을 이해하는 데 도움이되지 않습니다.

그러나하는 var text = "Some text " + variableName + "some more text."것은 게으르다.

편집 : @ 조그 당신은 의도적으로 단순한 대답에 뛰어 들었지만 토론에 아무것도 추가하지 않았습니다. 더 나은 예를 들어, 어떻 var items = doc.DocumentElement.FirstChild.ChildNodes;습니까? 유형을 알아낼 수 있다면 쿠키를 줄 것입니다.


18
당신이 알아낼 수없는 경우 "Some text "A는 string, 당신은 약의 수보다 걱정에 더 큰 문제가 var코드에서들.
Jörg W Mittag 2016 년

3
문제는 아니다 var. 문제는 crappy 변수 이름 "items"입니다. 좋은 변수 이름을 사용하면 아무 문제가 없습니다 var.
Kyralessa

3
항목이 XML 노드 모음이며 XML 노드 모음의 모든 속성과 메서드가 있어야한다고 생각합니다. 실제로 알아야합니다.
KutuluMike

var가 어떤 유형을 나타내는 지 알아야하고 바로보고 알 수없는 경우 마우스를 가져 가십시오. 그것을 알아내는 데별로 많은 것을 고려하지 않습니다.
scrwtp

1
"그냥 게으르다"-이것에 대한 논쟁이 아니다. 사실, 그것은 전혀 지능적이지 않습니다.
짐 발터

0

var를 사용하는 데 근본적인 문제가 있습니다.

이 예제에서는 모든 것이 나란히 있지만 문제는 실제로 공유 라이브러리 또는 프로젝트가있는 대규모 솔루션에 있습니다.

이걸 고려하세요:

public MyFirstObject GetMeAnObject() {
    return new MyFirstObject();
}

public void MainProgram() {
    var theObject = GetMeAnObject();
    theObject.PerformOperation();
}

다른 사람이 자신의 필요에 맞게 GetMeAnObject를 변경하면 어떻게됩니까?

public MySecondObject GetMeAnObject() {
    return new MySecondObject();
}

MainProgram 메서드는 .PerformOperation ()에서 큰 빨간색 오류가 발생합니다. 어떻게 된 거예요? PerformOperation은 이전에 완벽하게 작동했습니다. 우리는 theObject의 메소드를 보았고 추적없이 사라졌습니다. 지난번에 있었고 우리는 그 방법이 필요합니다. MyFirstObject에 PerformOperation이라는 메소드가있는 경우 꼬리를 추적하고 이유를 파악하려고 오랜 시간을 소비 할 수 있습니다. 모든 사람들은 GetMeAnObject가 MyFirstObject를 반환한다는 것을 "알고"있으므로이를 확인할 필요가 없습니다.

명시 적으로 theObject를 입력 한 경우 GetMeAnObject를 호출하는 행에 잘못된 Cast 오류가 발생하며 GetMeAnObject가 예상과 다른 유형을 반환한다는 것은 맹목적으로 알 수 있습니다.

즉, 명시 적 선언은 오류의 의미를 알고 있음을 의미합니다. 유효하지 않은 캐스트는 한 유형이 예상되었고 다른 유형이 리턴되었음을 의미합니다. 인식되지 않은 구성원은 구성원이 인식되지 않았 음을 의미합니다.


10
동료가 테스트에 포함되지 않은 코드를 크게 변경했으며 문제가 있다고 생각합니다 var. 언어는 이러한 종류의 동작으로부터 보호 할 수 없습니다. MyFirstObject를 직접 수정 한 경우 어떻게됩니까? 여전히 깨졌을 것입니다. 그러나 구문에서 당신을 구할 수 없었습니다. 나는 이것을 강도라고 생각합니다. varMySecondObject를 반환하는 대신 IMyFirstObject를 대신 반환하면 어떻게 될까요?
Phoshi

2
"모두가 GetMeAnObject가 MyFirstObject를 리턴한다는 것을"알고 있으므로 확인할 점이 없습니다. " 디버깅 할 경우 GetMeAnObject의 메모리에 실제로 의존하는 프로그래밍 시나리오를 실제로 생각할 수 없습니다. PerformOperation이 없는지 확인하면 코드를 보았을 것이고 다른 클래스를위한 것이 아닙니다. IDE에서 클래스가 인스턴스를 팝업하면 객체 유형을 봅니다. 실제로 컴파일러가 오류를 알려 주면 'MySecondObject 클래스에 PerformOperation 작업이 없습니다'라고 표시됩니다. 모든 사람이 어떻게 아는가?
Muhammad Alkarouri
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.