Tại sao ReSharper muốn sử dụng 'var' cho mọi thứ?


214

Tôi mới bắt đầu sử dụng ReSharper với Visual Studio (sau nhiều khuyến nghị về SO). Để dùng thử, tôi đã mở một dự án ASP.NET MVC gần đây. Một trong những điều đầu tiên và thường xuyên nhất mà tôi nhận thấy nó gợi ý là thay đổi hầu hết / tất cả các tuyên bố rõ ràng của tôi để varthay thế. Ví dụ:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

và như vậy, thậm chí với các loại đơn giản như int, boolvv

Tại sao điều này được khuyến khích? Tôi không đến từ nền tảng khoa học máy tính hoặc .NET, đã "rơi vào" sự phát triển .NET gần đây, vì vậy tôi thực sự muốn hiểu những gì đang diễn ra và liệu nó có lợi hay không.



27
Tôi đã suy nghĩ về điều này trong một thời gian và tôi đã đi đến kết luận rằng tôi nên luôn luôn sử dụng var, ngay cả khi loại này không rõ ràng! Lý do là bởi vì nó buộc tôi phải chọn tên mô tả nhất mà tôi có thể nghĩ ra và cuối cùng điều đó làm cho mã dễ đọc hơn nhiều. Cuối cùng, nó cũng giúp tách logic khỏi việc thực hiện. Tất nhiên đó chỉ là ý kiến ​​của tôi, tôi hy vọng nó sẽ giúp được ai đó;).
MasterMastic

Câu trả lời:


189

Một lý do là cải thiện khả năng đọc. Cái nào tốt hơn?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

hoặc là

var dictionary = new Dictionary<int, MyLongNamedObject>();

260
Tôi sẽ nói điều đầu tiên. Dễ dàng hơn để xem những gì đang xảy ra!
Mongus Pong

104
Nấm: Bạn có thích Bạn có thích Văn bản dự phòng Văn bản dự phòng không? : D
Mark Simpson

73
Rõ ràng là rõ ràng hơn theo ý kiến ​​của tôi. Sử dụng var để tạo nhiều đau đầu trong một số tình huống.
dùng1231231412

172
Tôi ghét nó khi các nhà phát triển sử dụng varcho tất cả mọi thứ - Tôi làm rất nhiều và rất nhiều ý mã sử dụng TFS (diffs dựa trên web) và nó làm cho công việc của tôi vô cùng khó khăn: ví dụ var items = GetSomeItems();vs IDataReader dr = GetSomeItems();Thiếu bằng tuyên bố trên cả nhưng dễ dàng hơn cho tôi để bắt khi sử dụng IDataReadervs var.
Chris Gessler

17
nếu bạn là nhà phát triển giỏi viết mã tốt và bạn đang sử dụng thư viện như Resharper, thì bạn không cần phải biết loại rõ ràng mà bạn giao dịch. Giống như khi bạn sử dụng các giao diện để khai báo hợp đồng, nhưng không phải là một lớp cụ thể, var cho phép bạn nói rằng bạn không quan tâm "kiểu" trả về là gì, bạn chỉ quan tâm nó làm gì và sử dụng các biến có tên tốt, cùng với với intelli-sense & resharper / VS helpers (chẳng hạn như CTRL + CLICK để điều hướng đến định nghĩa) sẽ giúp bạn đạt được 99%. Ngoài ra, sử dụng var có nghĩa là tôi không phải viết lại cơ sở mã của mình nếu tôi thay đổi kiểu trả về của phương thức.
Joshua Barker

286

Những gì ReSharper gợi ý rõ ràng là quá lạm dụng từ khóa var. Bạn có thể sử dụng nó trong đó loại rõ ràng:

var obj = new SomeObject();

Nếu loại không rõ ràng, bạn nên viết nó ra:

SomeObject obj = DB.SomeClass.GetObject(42);

36
Để chơi quỷ ủng hộ, có thể nếu loại không rõ ràng từ phương thức hoặc tên biến, nó chỉ ra một vấn đề với việc đặt tên nhiều hơn thì lạm dụng var. Tôi đồng ý về hiệu trưởng mặc dù, var chỉ nên được sử dụng khi nó không loại bỏ sự rõ ràng.
Matt Briggs

33
Trong trường hợp này, tôi muốn sử dụng tên biến tốt hơn. Về cơ bản, bạn đang đề xuất rằng chúng ta nhìn lên để xem biến được xác định ở đâu để tìm ra loại - Tôi đang đề xuất rằng chúng ta đặt tên cho các biến tốt hơn để chúng ta biết mục đích của biến đó.
Jaco Pretorius

18
@Jaco: +1, nhưng đáng để đề cập rằng thông tin về loại không được khuyến nghị ở tên biến. Ví dụ, ký hiệu Hungary không được coi là một thông lệ tốt.
La Mã Boiko

8
Việc cài đặt mặc định của ReSharper có bị lạm dụng hay không varlà vấn đề quan điểm và không "rõ ràng" điều này hay điều khác. Tôi không thích gõ những thứ mà trình biên dịch có thể tự tìm ra. Tôi thích suy luận kiểu C #, và thường ước nó tốt như suy luận kiểu F #. Nếu tôi có thể, tôi sẽ loại bỏ các loại rõ ràng khỏi các tham số phương thức và các kiểu trả về, như là tiêu chuẩn trong F #. Tất nhiên không phải ai cũng đồng ý.
Joel Mueller

15
@AnonymousType: Bạn vẫn còn thiếu điểm. Bạn đã nói rằng tên phương thức phải luôn phản ánh ý định của phương thức, nhưng ngay cả khi chúng làm điều đó không có nghĩa là tên chỉ định loại giá trị trả về. Phương pháp để đọc từ một Streamđối tượng chẳng hạn được đặt tên Read, không ReadAndReturnNumberOfBytesAsInt32.
Guffa

99

Cá nhân tôi thích tắt đề nghị này. Sử dụng varthường có thể cải thiện khả năng đọc; nhưng như bạn đã đề cập, đôi khi nó làm giảm nó (với các loại đơn giản hoặc khi loại kết quả bị che khuất ).

Tôi thích chọn khi tôi sử dụng varvà khi tôi không. Nhưng một lần nữa, đó chỉ là tôi.


11
Tôi nghĩ ReSharper có nghĩa là khá thông minh; Không nên đủ thông minh để biết khi nào loại kết quả là rõ ràng (ví dụ: bất cứ điều gì với từ khóa mới) và khi nào nó không rõ ràng?
DisgruntledGoat

3
Chà, tôi không biết tính đặc thù của tính năng này, nhưng tôi chắc chắn biết rằng tôi đã bị choáng ngợp bởi số lượng đề xuất mà nó đưa ra; Và tôi cũng sử dụng varkhá thường xuyên.
Bryan Menard

5
Tôi phát hiện ra rằng khi bạn luôn sử dụng var (như gợi ý chia sẻ lại), nó buộc bạn phải đặt tên cho các biến của mình đúng cách.
Sauleil

Bạn có thể tắt đề nghị?
Chris S

@AngeDeLaMort: vấn đề là nó buộc bạn phải sử dụng những cái tên không phù hợp var methodXYResultIntArray. Điều đó chống lại tất cả các tiêu chuẩn mã hóa và ít súc tích hơn int[] methodXYResult. Nếu bạn muốn trả về một byte[]từ phương thức trong tương lai, tất cả các tên biến của bạn đều sai. Với các loại rõ ràng, bạn có thể tái cấu trúc điều này rất dễ dàng. Có lý do để sử dụng var, với a Dictionary<string, List<SomeType<int>>>. Nhưng nếu tên đầy đủ không quá dài và bạn không sử dụng newở bên phải (hoặc một diễn viên rõ ràng) thì không nên đề xuất nó.
Tim Schmelter

69

varcó thể tăng khả năng đọc mã trong khi giảm mức độ hiểu mã ngay lập tức. Tương tự, nó có thể làm giảm khả năng đọc mã cho các tình huống khác. Đôi khi việc sử dụng nó là trung tính. Các biện pháp dễ đọc để hiểu không tỷ lệ thuận mà phụ thuộc vào tình huống. Đôi khi cả hai được tăng hoặc giảm cùng nhau.

Yếu tố là những gì varđang được áp dụng và mức độ mục tiêu hỗ trợ việc loại bỏ ngay lập tức loại dữ liệu của nó cho người đọc hoặc nếu thông tin loại của nó là cần thiết để hiểu được phần chương trình trong tay.

Ví dụ, việc đặt tên xấu có thể dẫn đến vargiảm khả năng hiểu mã. Đây không phải varlà lỗi của:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

Đôi khi nó không có ý nghĩa để sử dụng varcho các loại dữ liệu đơn giản khi mã dễ đọc hơn:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

Đôi khi varcó thể hữu ích để ẩn thông tin loại dữ liệu mà bạn không nhất thiết phải quan tâm để thấy sự phức tạp của:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

Bạn phải sử dụng varkhi có một loại ẩn danh vì không có tên loại để gọi nó bằng cách:

var o = new { Num=3, Name="" };

Khi bạn có Visual Studio Intellisense cung cấp thông tin loại bất chấp var, sau đó bạn cần ít dựa vào sự hiểu biết của mình thông qua việc đọc mã nghiêm ngặt mà không cần trợ giúp. Có lẽ khôn ngoan khi cho rằng không phải ai cũng có thể có hoặc sử dụng Intellisense.

Tóm lại dựa trên các ví dụ trên, tôi đề nghị áp dụng carte blush varkhông phải là một ý tưởng hay vì hầu hết mọi thứ đều được thực hiện tốt nhất trong chừng mực và dựa trên hoàn cảnh trong tay như được hiển thị ở đây.

Tại sao Resharper sử dụng tất cả trên mặc định? Tôi đề nghị cho dễ, bởi vì nó không thể phân tích các sắc thái của tình huống để quyết định khi nào tốt nhất không sử dụng nó.


5
IMHO ví dụ của bạn thực sự là lý do tốt để sử dụng var, nó sẽ buộc bạn phải viết tên phương thức đàng hoàng. GetNumber() -but what type?- tốt, tại sao bạn quan tâm? Nếu điều quan trọng cần biết, hãy gọi phương thức GetNumberAsDouble(), sau đó nó sẽ rõ ràng và sẽ hoạt động nếu bạn có một phương thức quay lại stringvà một phương thức trở lại double.
nicodemus13

10
@ nicodemus13 Bạn thường biết khi bạn quan tâm đến kiểu trả về của hàm khi bạn thực sự sử dụng giá trị trả về thay vì khi bạn tự viết hàm. Lược đồ đặt tên được đề xuất của bạn có thể dẫn đến lạm dụng như GetResultsAsIEnumerableOfDouble và tất cả những gì nó làm là chuyển thông tin loại bạn đã xóa khỏi bên trái của bài tập bằng cách sử dụng var sang bên phải của bài tập.
Eric

var value2 = Math.Abs ​​(-3); // Rõ ràng là một kiểu dữ liệu số. Xin lỗi, tôi hoàn toàn không đồng ý với điều này, vì phương pháp abs có 7 tình trạng quá tải dẫn đến không có gì ngoài sự tối nghĩa khi nhìn vào nó, imo
s1cart3r

var cũng có thể dẫn đến các lỗi logic tinh vi như: var counter = "0"; khi những gì bạn muốn là một số nguyên.
alaniane

42

Trong ReSharper (8.02, nhưng có thể là các phiên bản khác), tùy chọn "Sử dụng khai báo biến cục bộ được gõ ngầm" có thể được điều chỉnh theo sở thích của bạn , bất cứ điều gì có thể, bằng cách trước tiên mở menu tùy chọn cho ReSharper:

Menu Tùy chọn ReSharper

Sau đó, trong phần "Kiểm tra mã" bằng cách điều chỉnh "Mức độ kiểm tra" của ngôn ngữ bạn đã chọn, trong trường hợp của tôi c #:

Tắt đề xuất biến cục bộ

Như bạn có thể thấy, có các tùy chọn để điều chỉnh tất cả các đề xuất mà ReSharper đưa ra. Hy vọng điều này sẽ giúp những người như tôi đã có chiến lược sử dụng 'var' và chỉ muốn ReSharper tôn trọng nó :)


Điều này trả lời một câu hỏi khác nhau mà không được hỏi ở tất cả.
Carles Alcolea

9
Nhưng nó có liên quan đến nhiều người tìm kiếm nó khi đến đây. +1
Ori Nachum

24

Tôi ngạc nhiên khi không ai đề cập rằng việc thay đổi loại đối tượng được khởi tạo cũng dễ dàng hơn, bởi vì

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

là một hình thức lặp lại . Nếu tôi muốn thay đổi AVeryLongTypeNamethành một trong các lớp dẫn xuất của nó, tôi chỉ cần thay đổi điều này một lần khi sử dụng varvà vẫn có thể truy cập các phương thức của các lớp con.

Bên cạnh đó, khả năng đọc được cải thiện là một điểm quan trọng, nhưng như những người khác nói, var không nên bị lạm dụng, vì vậy tôi nghĩ tắt gợi ý trong Resharper là hoàn toàn ổn.


Rất hữu ích khi gọi các phương thức của nhà máy thay vì "mới"
Ian Ringrose

Nếu bạn cần sử dụng 'MyClass' khi ban đầu bạn viết mã và nó hoạt động, thì nó hoạt động. Khi bạn cần thay đổi nó, bạn phải đi và thay đổi nó ở mọi nơi, đặc biệt là khi bạn có giao diện liên quan. Mã không nên được coi như một bài luận, nó phải có ngữ nghĩa và được xác định rõ.
Piotr Kula

24

'var' là về việc rõ ràng

Cuộc tranh luận chính về việc có nên sử dụng vartừ khóa hay không là về mức độ dễ đọc của mã đối với bạn và các nhà phát triển khác.

Giống như bạn đang viết một câu chuyện, không có câu trả lời đúng. Nhưng hãy xem xét một số ví dụ về điều này bằng tiếng Anh.

Jake nói xin chào với Bill. Anh không thích anh nên anh quay lại và đi con đường khác.

Ai đã đi con đường khác? Jake hay Bill? Trong trường hợp này, sử dụng tên "Jake" và "Bill" giống như sử dụng tên loại. Và "Anh ấy" và "anh ấy" giống như sử dụng vartừ khóa. Trong trường hợp này nó có thể giúp được cụ thể hơn. Ví dụ sau đây rõ ràng hơn nhiều.

Jake nói xin chào với Bill. Jake không thích Bill nên anh quay lại và đi theo con đường khác.

Trong trường hợp này được cụ thể hơn làm cho câu rõ ràng hơn. Nhưng điều đó không phải lúc nào cũng đúng. Trong một số trường hợp cụ thể làm cho nó khó đọc hơn.

Bill thích sách, vì vậy Bill đã đến thư viện và Bill lấy ra một cuốn sách mà Bill luôn thích.

Trong trường hợp này, việc đọc câu sẽ dễ dàng hơn nếu chúng ta sử dụng "anh ấy" và trong một số trường hợp bỏ tên của anh ấy lại với nhau, tương đương với việc sử dụng vartừ khóa.

Bill thích sách, vì vậy anh đến thư viện và lấy ra một cuốn sách mà anh luôn thích.

Những ví dụ này bao gồm ý chính, nhưng chúng không nói lên toàn bộ câu chuyện. Trong những ví dụ đó chỉ có một cách để nói đến người đó. Hoặc bằng cách sử dụng tên của họ hoặc bằng cách sử dụng một thuật ngữ chung chung hơn như "anh ấy" và "anh ấy".

Trong trường hợp mã, chúng tôi có 3 cách để giúp thêm rõ ràng. Loại, tên biến và gán. Lấy dòng mã này làm ví dụ:

Person p = GetPerson();

Câu hỏi bây giờ là có đủ thông tin trong dòng mã đó để giúp bạn tìm hiểu chuyện gì đang xảy ra không?

Còn dòng mã sau đây thì sao? Bạn vẫn sẽ biết những gì pcó nghĩa là trong trường hợp này:

var p = GetPerson();

Làm thế nào bây giờ:

var p = Get();

Hay bây giờ:

var person = Get();

Hoặc cái này:

var t = GetPerson();

Hoặc này:

var u = Person.Get();

Việc từ khóa có varhoạt động trong một kịch bản nhất định hay không phụ thuộc rất nhiều vào ngữ cảnh của mã, như cách các biến, lớp và phương thức được đặt tên. Nó cũng phụ thuộc vào độ phức tạp của mã và phần còn lại của mã xung quanh nó.

Cá nhân tôi thích sử dụng vartừ khóa toàn diện hơn đối với tôi hầu hết thời gian. Nhưng tôi cũng có xu hướng đặt tên biến của mình theo loại để tôi không thực sự mất bất kỳ thông tin nào.

Điều đó nói rằng đôi khi tùy thuộc vào bối cảnh tôi đưa ra ngoại lệ, đó là bản chất của bất cứ điều gì phức tạp và phần mềm không là gì nếu không nói là phức tạp.


1
Tôi thích câu trả lời này nhất, bởi vì tôi không có gì chống lại varmiễn là tôi biết nó là gì trong khi đọc một dòng đó. Nếu tôi không biết phương thức nào từ một Giải pháp khác sử dụng một mô hình miền khác sẽ trả về, thì tôi muốn loại đó được xác định rõ ràng, làm cho nó dễ đọc hơn nhiều. +1
Piotr Kula

Trong tất cả các trường hợp của bạn mà loại trả về không rõ ràng, tôi đồng ý rằng bạn không nên sử dụng var vì hiện tại bạn đang bỏ qua thông tin hữu ích.
cuộn

18

Tôi không thích điều này là tốt.

Tôi không muốn điều này biến thành một cuộc tranh luận về việc sử dụng var, nó có công dụng của nó nhưng không nên được sử dụng ở mọi nơi.

Điều quan trọng cần nhớ là ReSharper được cấu hình theo bất kỳ tiêu chuẩn mã hóa nào bạn muốn.

Chỉnh sửa: ReSharper và var


13
Sau một năm chống cự, tôi sử dụng var khá nhiều.
LiamB

15

Tôi thấy nhiều câu trả lời đúng, nhưng thiếu câu trả lời đầy đủ.

Đúng là ReSharper lạm vardụng theo mặc định. Tôi nghĩ rằng hầu hết mọi người sẽ đồng ý với điều đó. Nó cũng dễ đọc hơn khi varđược sử dụng và loại rõ ràng như khi bạn sử dụng một newcâu lệnh. Tôi thấy một bài viết cho thấy cách cập nhật mức độ nghiêm trọng kiểm tra để chỉ hiển thị gợi ý cho việc sử dụng var.

Tôi đã cố gắng bình luận trên các bài đăng khác trước để thêm vị trí đặt những bài này nhưng không có tiếng tăm. Rõ ràng, tôi cũng không có tiếng để đăng ảnh chụp màn hình của tôi về các cài đặt.

Tôi sẽ giải thích làm thế nào để đạt được điều đó.

Trong Visual Studio> Menu chính> Chia sẻ lại> Tùy chọn> Chỉnh sửa mã> C #> Kiểu mã> Sử dụng Var trong khai báo

  • Đối với loại tích hợp Sử dụng loại rõ ràng
  • Đối với các loại đơn giản Sử dụng 'var' khi hiển nhiên
  • Ở nơi khác sử dụng'var '

nhập mô tả hình ảnh ở đây

Tài liệu trợ giúp của ReSharper: Kiểu cú pháp mã: Nhập ngầm định / gõ ngầm ('var' Keyword) - Định cấu hình tùy chọn sử dụng từ khóa 'var'


Điều này nên được đánh dấu là câu trả lời chính xác bên ngoài các cuộc tranh luận var, đây là cách tiếp cận cân bằng
Brian Ogden

Bạn có thể đưa ra một ví dụ về cách "nơi hiển nhiên" được quyết định?
cuộn


13

Quy tắc của tôi là thế này:

  • Bạn đang tuyên bố một loại nguyên thủy (tức là byte, char, string, int[], double?, decimal, vv)? -> Sử dụng loại:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
  • Bạn đang tuyên bố một loại phức tạp (ví dụ List<T>, Dictionary<T, T>, MyObj)? -> Sử dụng var:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();

Tôi muốn không đồng ý, string myStr = "foo";rõ ràng đó là một chuỗi. Tôi sẽ đưa tất cả các ví dụ của bạn vào sử dụng danh mục var ... và các khai báo được trả về từ một phương thức để sử dụng kiểu khám phá. Nhưng vào cuối ngày, đó là bất cứ điều gì bạn và nhóm của bạn cảm thấy tốt hơn cho dự án cụ thể.
Dean Meehan

12

Tôi chỉ muốn chỉ ra rằng việc sử dụng "var" được khuyến nghị trong các Quy ước mã hóa C #

khi loại biến rõ ràng từ phía bên phải của bài tập hoặc khi loại chính xác không quan trọng

Vì vậy, đó có thể là lý do tại sao mẹo được bật theo mặc định trong ReSharper. Họ cũng cung cấp một số trường hợp không cải thiện khả năng đọc ngay bên dưới trong cùng một tài liệu.


Điều đó thật tuyệt vời khi bạn biết rằng loại này đến từ System.Diagnostics.PerformanceCounter() - Bạn có thể dễ dàng biết được bộ đếm độ hoàn hảo của nó từ lớp chẩn đoán tích hợp. Nhưng loại nào được trả lại ở đây? var thingyMaBob = GetThatSpecialThing(18,null,(MyEnum)2)? Không có đầu mối đồng hồ, đặc biệt nếu bạn có hơn 100 dự án trong giải pháp của bạn.
Piotr Kula

"Được khuyến nghị khi loại biến là rõ ràng" và "Họ cũng cung cấp một số trường hợp nó không cải thiện khả năng đọc ngay bên dưới trong cùng một tài liệu". Thành thật mà nói, tôi nghĩ rằng tôi đã bỏ lỡ quan điểm của bạn. Câu trả lời của tôi nói điều tương tự bạn nói.
jose

6

ReSharper khuyến nghị varvì nó có xu hướng giải phóng việc tạo đối tượng.

So sánh hai ví dụ sau:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

Nó chỉ là một tốc ký được cho là dễ đọc hơn.

Tôi nghĩ sẽ ổn khi bạn tạo đối tượng mới một cách rõ ràng bằng "mới". Trong ví dụ của bạn, tuy nhiên, có thể không rõ ràng nếu các lớp không được đặt tên đúng.


6

BTW, ReSharper rút ra sự khác biệt giữa 'bạn có thể muốn áp dụng đề xuất này cho mã của mình' và 'mã của bạn bị hỏng, muốn tôi sửa nó?'. Các vartừ khóa là trong hạng mục đề nghị, cùng với những câu như "nghịch nếu để giảm làm tổ"; bạn không cần phải theo nó

Bạn có thể định cấu hình mức độ khó chịu của từng cảnh báo thông qua hộp thoại Tùy chọn hoặc trực tiếp thông qua menu bật lên cho cảnh báo đó. Bạn có thể hạ cấp những thứ như varđề xuất để chúng ít nổi bật hơn hoặc bạn có thể nâng cấp những thứ như cảnh báo 'sử dụng phương thức mở rộng' để nó hiển thị như một lỗi thực tế.


5

Các vartính năng của Net 3.0 chỉ là suy luận kiểu , đó là loại an toàn và thường làm cho mã của bạn dễ đọc hơn. Nhưng bạn không cần phải và có thể tắt đề xuất đó trong việc chia sẻ lại nếu bạn muốn.


4

Var thật tuyệt vời! Tôi đã bắt gặp nhiều nhà phát triển có ấn tượng varbị ràng buộc với một loại động, không phải vậy. Nó vẫn được gõ tĩnh, nó chỉ do trình biên dịch quyết định.

Dưới đây là một số tích cực tuyệt vời của việc sử dụng var

Việc gõ var ít hơn và dễ đọc hơn, ví dụ như

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()Yuk.

var postcodes = new Dictionary<int,IList<string>>()\ o / \ o /

Tên biến mô tả khác - một tên khó hiểu nhưng tôi nghĩ điều quan trọng là phải để bản chất lỏng của sự vartỏa sáng ở đây. Như varlà một chút mơ hồ, nó thực sự khuyến khích một tên biến giải thích hơn là để cho loại nói cho chính nó.

Thay đổi mã ít hơn - nếu kiểu trả về của một cuộc gọi phương thức thay đổi. Bạn chỉ phải thay đổi cuộc gọi phương thức, không phải mọi nơi nó được sử dụng.

Các loại ẩn danh - các loại ẩn danh là một khái niệm thực sự mạnh mẽ, đặc biệt là trong các lĩnh vực như tài nguyên một phần của WebApi . Không có var, chúng không thể được sử dụng.

Tuy nhiên, đôi khi rất hữu ích khi khai báo các loại và tôi thấy điều này hữu ích nhất trong các nguyên thủy hoặc cấu trúc. Chẳng hạn, cá nhân tôi thấy cú pháp này rất hữu ích:

for(var i = 0; i < 10; i++) 
{

}

đấu với

for(int i = 0; i < 10; i++) 
{

}

Tất cả tùy thuộc vào sở thích cá nhân nhưng sử dụng varthực sự sẽ tăng tốc độ phát triển của bạn và mở khóa cả một thế giới tốt đẹp loại ẩn danh.


2

Không có sự khác biệt kỹ thuật, nếu bạn sử dụng var, loại được ngụ ý bởi trình biên dịch. Nếu bạn có một mã như thế này:

var x = 1;

x được ngụ ý là một int và không có giá trị nào khác có thể được gán cho nó.

Từ khóa var rất hữu ích nếu bạn thay đổi loại biến; sau đó bạn chỉ phải thực hiện một thay đổi thay vì hai:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";

1
@AlexKamburov mã 10 dòng dưới đây sẽ bị hỏng, không liên quan đến var.
user3285954

1
@ user3285954 Trong một số trường hợp, var có thể che giấu vấn đề và đó là khi mọi thứ trở nên tồi tệ. Vấn đề không nằm ở việc viết mã, vấn đề nằm ở khả năng bảo trì. Một số người cho rằng nó sạch hơn với var nhưng đôi khi tôi thấy nó là sự xáo trộn. Nó gần với một cuộc tranh luận tôn giáo. brad-smith.info/blog/archives/336 Cá nhân tôi chỉ sử dụng var cho các câu lệnh Linq và những nơi khác khi khai báo kiểu này thực sự dài dòng. Tôi nghĩ rằng var là một bổ sung tốt và mọi người cần xem các bình luận của Anders Hejlsberg về lý do giới thiệu nó.
Alex Kamburov

2

Các vartừ khóa được giới thiệu trong C # 3.0 - nó cho phép chúng ta quên đi quy định cụ thể loại của chúng tôi một cách rõ ràng.

Không có sự khác biệt thực sự cho dù bạn sử dụng

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

hoặc là

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

ngoại trừ khả năng đọc thuần túy và ít cơ hội cho lỗi.

Nó có vẻ như một ví dụ sáo rỗng, nhưng nói những điều sau đây có thể giúp bạn hiểu:

var myInt = 23;

trả về một intloại, trong khi

var myInt = "23";

trả về một stringloại.

Tham chiếu MSDN


2

Việc chỉ định một loại đối tượng rõ ràng là bằng cách nào đó dư thừa. Ngay cả khi được dịch bằng tiếng Anh, nó nghe có vẻ dư thừa: "đặt một đối tượng loại X vào một biến loại X" so với "Đặt một đối tượng loại X vào một biến".

Tuy nhiên, sử dụng 'var' có những hạn chế của nó . Nó ngăn chặn việc sử dụng đa hình dưới đây là vẻ đẹp thuần túy :

Giả sử một con chó kéo dài động vật; Cat mở rộng phân cấp lớp Động vật:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

Cùng một mã, với x được khai báo với 'var' sẽ không biên dịch .

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

Dù sao, trở lại câu hỏi ban đầu, tôi không sử dụng Resharper, nhưng tôi cho rằng điều đó đủ thông minh để phát hiện khi nào không sử dụng 'var'. :-)


4
Không cần đúc (với as) là thuần túy khủng khiếp. Bạn biến lỗi biên dịch thành lỗi thời gian chạy nếu bạn có một cái gì đó như Animal x = new Cat(); DoStuffWithDog(x as Dog); Tại sao lại sử dụng x? Dog x = new Dog (), Cat y = new Cat (), bùng nổ không còn mơ hồ nữa.
Đánh dấu Sowul

truyền (có 'như' hoặc không) có thể dẫn đến lỗi thời gian chạy. Điều gì là 'khủng khiếp' về việc casting khi bạn biết bạn đang làm gì? Tại sao phải sử dụng lại x? Ví dụ ở đây là minh họa. Mục tiêu của ví dụ là chỉ ra cách sử dụng 'var' có thể dẫn đến các hạn chế khi tham chiếu có nghĩa là đa hình.
xtrem

5
Không, không thể: tính đa hình trái ngược với những gì đang diễn ra ở đây. Điều này đang cố gắng truyền các đối tượng kiểu Animalvào các phương thức lấy DogCat. Đa hình là đảo ngược: vì vậy bạn có thể truyền các đối tượng loại DogCatvào một phương thức Animal, ví dụ void Walk(Animal a): Walk(new Cat()),Walk(new Dog())
Mark Sowul

Bạn không nên sử dụng lại các biến theo cách này, dẫn đến các lỗi rất khó chịu. Không quá rõ ràng trong các phương thức ngắn nhưng khi bạn có 15-20 dòng mã, bạn sẽ quên x là gì. Đừng lười biếng: var dog = new Dog (); DoStuff (chó); mèo var = mèo mới (); DoStuff (mèo);
user3285954

2
Không đánh nhau. Tôi không có cảm giác với bất kỳ cách khai báo biến nào (ẩn hoặc rõ ràng). Tôi thực sự sử dụng ít nhất một trong mỗi ngày. Tôi chỉ đơn giản nhấn mạnh rằng khi bạn chọn phương thức ẩn (var), trình biên dịch sẽ quyết định loại hẹp nhất có thể cho bạn. Mà có thể không phải luôn luôn là những gì bạn muốn. Đó là tất cả.
xtrem

2

Theo quan điểm của tôi, var chỉ nên được sử dụng khi nó rõ ràng ngay lập tức loại là gì khi xác định giá trị của biến.

Thí dụ:

var s = "string value";

Rõ ràng đó slà một string.

Tôi tin rằng nó cũng thích hợp khi tên loại biến rất phức tạp.

Thí dụ:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

Ngoài những tình huống này, tôi không thấy GAIN nào được thực hiện bằng cách sử dụng var , nhưng tôi có thể nghĩ về một số tình huống có thể gây bất lợi:

Ví dụ, một loại dùng một lần có giá trị biến bên phải không hiển thị rõ ràng loại đó. Việc vứt bỏ IDis Dùng có thể dễ dàng bị lãng quên

Thí dụ:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.

1

'var' thêm một loại phần tử "động" vào mã của bạn (mặc dù mã tất nhiên vẫn được nhập đúng). Tôi khuyên bạn không nên sử dụng nó trong trường hợp loại không rõ ràng. Xem xét ví dụ này:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

Nếu loại trả về của GetTheObjectFromDatabase () được thay đổi từ Loại A thành B, chúng tôi sẽ không nhận thấy, vì cả hai Lớp đều triển khai DoS Something (). Mã, tuy nhiên, bây giờ thực sự có thể làm một cái gì đó hoàn toàn khác.

Điều này có thể tinh tế như cả việc viết các nội dung khác nhau vào nhật ký, vì vậy bạn có thể không nhận thấy đơn vị quá muộn.

Việc sử dụng var sau đây sẽ luôn ổn:

var abc = new Something();

1

Đối với những người không thích sử dụng "var" liên tục, bạn cũng có thể ngăn ReSharper mặc định thành var khi thực hiện "giới thiệu biến". Đây là điều khiến tôi thất vọng trong một thời gian dài, nó luôn được mặc định là var và tôi đã thay đổi nó mỗi lần.

Các cài đặt này nằm trong Chỉnh sửa mã> C #> Kiểu mã

nhập mô tả hình ảnh ở đây


0

Không có sự khác biệt về kỹ thuật (như eWolf đã chỉ ra). Bạn có thể sử dụng cái này hoặc cái kia, mã CLR được tạo sẽ trông giống nhau.

Theo tôi lợi ích chính là điều này có xu hướng buộc bạn phải sử dụng cách đặt tên biến tốt hơn. Trong ví dụ của bạn, 'foo' là một lựa chọn khá kém cho một tên biến.


0

Theo JetBrains (tác giả của ReSharper), họ khuyến khích sử dụng var theo mặc định.

Từ trang web của họ :

Việc sử dụng các biến cục bộ được gõ ngầm (còn được gọi là vartừ khóa) được giới thiệu trong C # 3.0 đã trở nên khá phổ biến vì nó cải thiện khả năng đọc trong nhiều tình huống. Theo mặc định, ReSharper cũng khuyến khích sử dụng vartừ khóa, nhưng các tùy chọn sử dụng của nó có thể cấu hình linh hoạt - ví dụ: bạn có thể chọn sử dụng các loại rõ ràng trong các trường hợp cụ thể hoặc ở mọi nơi và ReSharper sẽ giúp bạn thực thi các tùy chọn của mình.


Tôi có thể cấu hình ở đâu khi yêu cầu khai báo kiểu rõ ràng?
dùng764754
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.