C #에서 var 키워드 사용 후 var를 통한 유형 유추의 적절한 사용에

C # 3에서 ‘var’키워드 사용에 대해 동료들과 토론 한 후 var를 통한 유형 유추의 적절한 사용에 대한 사람들의 의견이 궁금했습니다.

예를 들어, 나는 의심스러운 상황에서 var를 게으르게 사용했습니다.

foreach(var item in someList) { // ... } // Type of 'item' not clear.
var something = someObject.SomeProperty; // Type of 'something' not clear.
var something = someMethod(); // Type of 'something' not clear.

var의 합법적 사용은 다음과 같습니다.

var l = new List<string>(); // Obvious what l will be.
var s = new SomeClass(); // Obvious what s will be.

흥미롭게도 LINQ는 약간 회색 영역으로 보입니다.

var results = from r in dataContext.SomeTable
              select r; // Not *entirely clear* what results will be here.

IEnumerable을 구현하는 유형이 될 것이라는 결과는 분명하지만 새로운 객체를 선언하는 var와 같은 방식으로 완전히 명확하지는 않습니다.

LINQ가 객체와 관련하여 더 나쁩니다.

var results = from item in someList
              where item != 3
              select item;

이것은 동등한 foreach (var list in someList) {// …} 동등성보다 낫습니다.

예를 들어 IEnumerable <int> 및 IEnumerable <double>을 허용하는 오버로드 된 메서드에 해당 쿼리 결과를 배치하려는 경우 호출자가 실수로 잘못된 형식으로 전달할 수 있습니다.

var 않는 당신이 의도하지 않게하는 방법에 잘못된 유형을 통과 할 때, 과부하 평균 컴파일러 오류가 발행되지 않을 때 확대되는 것을 강력한 입력을 유지하지만, 질문 유형이 정의에 즉시 나타나지 않을 것이 위험하다 정말 여부입니다.



답변

여전히 var어떤 경우에는 코드를 더 읽기 쉽게 만들 수 있다고 생각 합니다. Orders 속성이있는 Customer 클래스가 있고이를 변수에 할당하려면 다음과 같이하십시오.

var orders = cust.Orders;

Customer.Orders가인지 상관하지 않습니다 IEnumerable<Order>. ObservableCollection<Order>또는 BindingList<Order>원하는 것은 목록을 메모리에 유지하여 목록을 반복하거나 나중에 계산하는 것입니다.

위의 선언을 다음과 대조하십시오.

ObservableCollection<Order> orders = cust.Orders;

나에게 유형 이름은 소음입니다. 그리고 돌아가서 Customer의 유형을 변경하기로 결정하면 (예 : ObservableCollection<Order>에서 IList<Order>) 추적 을 선언해야합니다. 첫 번째에서 var를 사용하면 수행 할 필요가없는 선언도 변경해야합니다. 장소.


답변

var폭넓게 사용 하고 있습니다. 이것이 코드의 가독성을 떨어 뜨린다는 비판이 있지만, 그 주장을 뒷받침하는 주장은 없습니다.

물론, 우리가 다루는 유형이 명확하지 않다는 것을 의미 할 수 있습니다. 그래서 무엇? 이것은 실제로 분리 된 디자인의 요점입니다. 인터페이스를 다룰 때 변수의 유형에 크게 관심이 없습니다 . var나는 이것을 훨씬 더 진실로 받아들이지 만, 인수는 가독성 관점에서 동일하게 유지된다고 생각한다. 프로그래머는 실제로 변수의 유형에 관심을 두지 말고 변수 하는 것에 관심을 가져야한다 . 이것이 바로 Microsoft가 유형 추론을 “덕 타이핑”이라고 부르는 이유입니다.

그래서 변수를 사용하여 선언 할 때 변수는 무엇을 var합니까? IntelliSense가 알려주는 모든 작업을 쉽게 수행 할 수 있습니다. IDE를 무시하는 C #에 대한 추론은 실제로 부족합니다. 실제로 모든 C # 코드는 IntelliSense를 지원하는 IDE에서 프로그래밍됩니다.

var선언 된 변수를 사용 하고 변수가 무엇인지 혼동하면 코드에 근본적으로 문제가 있습니다. var원인이 아니라 증상 만 보이게합니다. 메신저를 비난하지 마십시오.

이제 C # 팀은 익명 형식을 생성하는 LINQ 문의 결과를 캡처하는 데만var 사용해야 하는 코딩 지침을 발표했습니다 (여기서는 실제 대안이 없습니다 ). 음, 나사로 조이십시오. C # 팀이이 가이드 라인에 대해 건전한 주장을하지 않는 한, 전문적이고 개인적인 견해로는 순수한 외롭기 때문에 무시할 것입니다. (죄송합니다. 해당 가이드 라인에 대한 링크가 없습니다.)var

실제로, 왜 당신이 사용하지 말아야하는지에 대한 (표면적으로) 좋은 설명이var 있지만 여전히 그것들이 크게 잘못되었다고 생각합니다. “searchabililty”의 예를 보자. 저자 는 사용 된 var장소를 찾기가 어렵다고 주장한다 MyType. 권리. 인터페이스도 마찬가지입니다. 실제로 왜 수업이 사용되는지 알고 싶습니까? 인스턴스화 된 위치에 더 관심이있을 수 있으며 생성자가 호출되어야하는 곳이기 때문에 여전히 검색 할 수 있습니다 (간접적으로 수행 된 경우에도 유형 이름을 어딘가에 언급해야 함).


답변

내 의견으로는 C #에서 Var는 좋은 것입니다 tm . 이렇게 유형이 지정된 변수는 여전히 강력한 유형이지만 변수가 정의 된 할당의 오른쪽에서 유형을 가져옵니다. 유형 정보는 오른쪽에서 사용할 수 있기 때문에 대부분의 경우 왼쪽에서 입력해야하는 것은 불필요하고 너무 장황합니다. 나는 이것이 타입 안전성을 줄이지 않고 가독성을 크게 향상 시킨다고 생각합니다.

필자의 관점에서 변수와 메소드에 대한 좋은 명명 규칙을 사용하는 것이 명시 적 유형 정보보다 가독성 관점에서 더 중요합니다. 유형 정보가 필요한 경우 항상 변수 (VS) 위에 마우스를 가져 와서 얻을 수 있습니다. 그러나 일반적으로 독자에게 명시적인 유형 정보는 필요하지 않습니다. 개발자의 경우 VS에서는 변수 선언 방법에 관계없이 여전히 Intellisense를 얻습니다. 이 모든 것을 말했지만 유형을 명시 적으로 선언하는 것이 합리적 인 경우가 있습니다. 아마도를 반환하는 메소드가 List<T>있지만 유형을IEnumerable<T>당신의 방법으로. 인터페이스를 사용하고 있는지 확인하기 위해 인터페이스 유형의 변수를 선언하면이를 명시 적으로 만들 수 있습니다. 또는 초기 값없이 변수를 선언하려고합니다. 어떤 조건에 따라 즉시 값을 가져 오기 때문입니다. 이 경우 유형이 필요합니다. 유형 정보가 유용하거나 필요한 경우 계속 진행하십시오. 그러나 필자는 일반적으로 필요하지 않으며 대부분의 경우 코드가 없으면 코드를 쉽게 읽을 수 있다고 생각합니다.


답변

그것들 중 어느 것도 절대 사실이 아닙니다. var가독성에 긍정적이고 부정적인 영향을 줄 수 있습니다. 제 생각 var에는 다음 중 하나에 해당하면 사용해야합니다.

  1. 유형은 익명입니다 ( 이 경우 var 이어야 하므로 여기서 선택할 수 없습니다 )
  2. 유형이 지정된 표현에 명백한 근거 (즉 var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

var구문 설탕이므로 성능에 영향을 미치지 않습니다. 컴파일러는 형식을 유추하고 IL로 컴파일 된 후에 형식을 정의합니다. 실제로 역동적 인 것은 없습니다 .


답변

C # 팀의 수석 소프트웨어 디자인 엔지니어 인 Eric Lippert

var키워드가 도입 된 이유는 무엇 입니까?

두 가지 이유가 있습니다. 하나는 오늘날 존재하며 다른 하나는 3.0에서 자랍니다.

첫 번째 이유는이 코드가 모든 중복성으로 인해 매우 추악하기 때문입니다.

Dictionary<string, List<int>> mylists = new Dictionary<string, List<int>>();

그리고 그것은 간단한 예입니다 – 나는 더 나빠졌습니다. 정확히 같은 것을 두 번 입력해야 할 때마다 그것은 우리가 제거 할 수있는 중복입니다. 쓰는 것이 훨씬 좋습니다

var mylists = new Dictionary<string,List<int>>();

그리고 컴파일러가 할당을 기반으로 유형이 무엇인지 알아 내도록하십시오.

둘째, C # 3.0은 익명 형식을 도입했습니다. 정의에 의해 익명의 종류에는 이름이 없기 때문에, 당신은 필요 의 유형은 익명 인 경우 초기화 표현에서 변수의 유형을 추론 할 수.

강조합니다. 전체 기사 C # 3.0은 여전히 ​​정적으로 유형이 정직합니다! 그리고 다음 시리즈 는 꽤 좋습니다.

이것은 무엇 var을위한 것입니다. 다른 용도로는 잘 작동하지 않을 수 있습니다. JScript, VBScript 또는 동적 타이핑과의 비교는 총 이층입니다. 참고 다시 var됩니다 필요한 .NET에서 기타 특정 기능이 작동을하기 위해.


답변

var의 사용은 현명하게 선택된 변수 이름과 결합되어야한다고 생각합니다.

다음과 같은 경우 foreach 문에서 var를 사용하는 데 아무런 문제가 없습니다.

foreach (var c in list) { ... }

이 같은 경우 :

foreach (var customer in list) { ... }

… 코드를 읽는 사람은 “목록”이 무엇인지 이해할 가능성이 훨씬 높습니다. 리스트 변수 자체의 이름을 제어 할 수 있다면 더 좋습니다.

다른 상황에도 동일하게 적용될 수 있습니다. 이것은 쓸모가 없습니다.

var x = SaveFoo(foo);

… 그러나 이것은 의미가 있습니다.

var saveSucceeded = SaveFoo(foo);

각자 자신의 것으로 생각합니다. 나는 이것을하는 것을 발견했다.

var f = (float)3;

12 단계 var 프로그램이 필요합니다. 내 이름은 매트이고 나는 var를 사용합니다.


답변

우리는 새로운 개발보다 유지 관리 모드에서 여러 번 더 오랜 시간을 소비한다는 가정을 바탕으로 “기계가 아닌 사람을위한 코드”라는 개념을 채택했습니다.

저에게는 컴파일러가 변수의 유형을 “알고있다”는 주장을 배제합니다. 컴파일러가 코드 컴파일을 중지하기 때문에 처음에는 잘못된 코드를 작성할 수 없지만 다음 개발자가 코드를 읽을 때 6 개월 만에 변수가 올바르게 또는 부정확하게 수행하는 작업을 추론하고 문제의 원인을 신속하게 파악할 수 있어야합니다.

그러므로,

var something = SomeMethod();

코딩 표준에 의해 금지되지만 가독성을 높이기 위해 팀에서 다음을 권장합니다.

var list = new List<KeyValuePair<string, double>>();
FillList( list );
foreach( var item in list ) {
   DoWork( item );
}