Sử dụng từ khóa var trong C #


406

Sau khi thảo luận với các đồng nghiệp về việc sử dụng từ khóa 'var' trong C # 3, tôi tự hỏi ý kiến ​​của mọi người về cách sử dụng suy luận kiểu thông qua var là gì?

Ví dụ: tôi khá lười sử dụng var trong các trường hợp nghi vấn, ví dụ: -

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.

Việc sử dụng var hợp pháp hơn như sau: -

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

Thú vị là LINQ dường như là một chút của một khu vực màu xám, ví dụ: -

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

Rõ ràng kết quả sẽ là gì khi nó sẽ là một kiểu thực hiện IEnumerable, tuy nhiên nó không hoàn toàn rõ ràng giống như cách một var khai báo một đối tượng mới.

Thậm chí còn tệ hơn khi nói đến LINQ cho các đối tượng, ví dụ: -

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

Điều này không tốt hơn so với foreach tương đương (mục var trong someList) {// ...} tương đương.

Có một mối quan tâm thực sự về an toàn kiểu ở đây - ví dụ: nếu chúng ta đặt kết quả của truy vấn đó vào một phương thức quá tải chấp nhận IEnumerable <int> và IEnumerable <double> thì người gọi có thể vô tình chuyển nhầm loại.

var không duy trì kiểu gõ mạnh nhưng câu hỏi thực sự là liệu nó có nguy hiểm khi loại không rõ ràng ngay lập tức về định nghĩa hay không, điều gì đó được phóng to khi quá tải có nghĩa là lỗi trình biên dịch có thể không được đưa ra khi bạn vô tình chuyển sai loại cho phương thức.


68
Sử dụng var là tốt, nhưng "Tôi không phải tìm ra loại" có vẻ như là một lý do rất tồi để sử dụng nó ... bạn phải biết loại đó là gì, var chỉ là một phím tắt để tránh gõ nó
Thomas Levesque

53
var i = 0;== thất bại! var c = new CrazyFrigginLongClassName();== thắng!
dotjoe

6
"Var cũng nhắc nhở tôi về loại biến thể VB / VBA. Nó cũng có vị trí của nó. Tôi nhớ lại (từ nhiều năm trước) việc sử dụng của nó là loại ít hơn mong muốn và nó khá đói tài nguyên." <- cho thấy đây là một câu hỏi đánh lừa vì loại C # 'var' không liên quan gì đến loại biến thể VB / VBA.
dùng7116

20
var readabilityBeDamned = true;
spoulson

9
Vấn đề với tất cả các ví dụ được nêu ở đây là chúng tôi đang xem xét MỘT dòng mã. Khi tôi thấy dòng sau dòng khai báo "var", cái này nối tiếp cái kia, nó sẽ ra khỏi tầm tay. Khả năng đọc là chủ quan, nhưng tôi thấy var bị lạm dụng nhiều hơn so với sử dụng một cách tôn trọng.
JRO

Câu trả lời:


293

Tôi vẫn nghĩ rằng varcó thể làm cho mã dễ đọc hơn trong một số trường hợp. Nếu tôi có một lớp Khách hàng có thuộc tính Đơn hàng và tôi muốn gán nó cho một biến, tôi sẽ chỉ làm điều này:

var orders = cust.Orders;

Tôi không quan tâm nếu Khách hàng. Các giao dịch là IEnumerable<Order>, ObservableCollection<Order>hoặc BindingList<Order>- tất cả những gì tôi muốn là giữ danh sách đó trong bộ nhớ để lặp lại hoặc lấy số liệu của nó hoặc một cái gì đó sau này.

Đối chiếu với tuyên bố trên với:

ObservableCollection<Order> orders = cust.Orders;

Đối với tôi, tên loại chỉ là tiếng ồn. Và nếu tôi quay lại và quyết định thay đổi loại Khách hàng. Hãy theo dõi (nói từ ObservableCollection<Order>thành IList<Order>) thì tôi cũng cần thay đổi tuyên bố đó - điều mà tôi sẽ không phải làm nếu tôi sử dụng var trong lần đầu tiên địa điểm.


48
Tôi thích có loại rõ ràng trước mặt tôi khi tôi đang đọc mã. Làm thế nào để tôi biết "mã xác nhận" ở đây không có loại nào? Vâng, tôi có thể di chuột qua để tìm hiểu, nhưng tại sao tôi phải làm vậy? :)
Jon Tackabury

77
Nhưng vấn đề là nói chung nó không thành vấn đề. Được cung cấp quyền giám sát. Các giao dịch là thứ bạn có thể liệt kê (ví dụ: foreach over), không quan trọng nó thuộc loại nào. Các mã bổ sung chỉ là trong cách đọc ý định.
Matt Hamilton

67
Nhưng nếu bạn chỉ yêu cầu quyền giám sát đó. Các giao dịch là "thứ gì đó bạn có thể liệt kê" thì bạn không tuyên bố nó là một <Lệnh> có thể làm cho yêu cầu đó rõ ràng và rõ ràng không? Tuyên bố nó là var có nghĩa là bạn thực sự mất yêu cầu đó.
GrahamS

5
@jon và làm thế nào các đơn đặt hàng IEnumerbal = mãng cầu. Các lệnh foreach (thứ tự var trong đơn đặt hàng) sẽ tạo ra sự khác biệt? điều duy nhất IEnumerable nói là bạn có thể đưa nó vào một mục trước nhưng bạn đã biết điều đó từ dòng bên dưới
Rune FS

18
"Điều duy nhất IEnumerable nói là bạn có thể đưa nó vào một mục trước" - nó cũng thể hiện ý định rằng điều duy nhất bạn có thể làm là liệt kê. Sử dụng var cung cấp quyền truy cập và intellisense cho các thành viên công cộng của loại bộ sưu tập cụ thể.
Joe

167

Tôi sử dụng varrộng rãi. Đã có những chỉ trích rằng điều này làm giảm khả năng đọc của mã, nhưng không có đối số để hỗ trợ cho tuyên bố đó.

Phải thừa nhận rằng điều đó có nghĩa là chúng ta không rõ chúng ta đang đối phó với loại nào. Vậy thì sao? Đây thực sự là điểm của một thiết kế tách rời. Khi làm việc với các giao diện, bạn hoàn toàn không quan tâm đến loại mà một biến có. varđưa điều này đi xa hơn, đúng, nhưng tôi nghĩ rằng đối số vẫn giống nhau từ quan điểm dễ đọc: Lập trình viên thực sự không nên quan tâm đến loại biến mà là những gì một biến làm . Đây là lý do tại sao Microsoft cũng gọi kiểu gõ suy luận vịt gõ.

Vì vậy, một biến làm gì khi tôi khai báo nó bằng cách sử dụng var? Thật dễ dàng, nó làm bất cứ điều gì IntelliSense nói với tôi. Bất kỳ lý do nào về C # mà bỏ qua IDE đều thiếu thực tế. Trong thực tế, mọi mã C # được lập trình trong một IDE hỗ trợ IntelliSense.

Nếu tôi đang sử dụng một varbiến được khai báo và bị nhầm lẫn về biến đó là gì, thì về cơ bản có gì đó không đúng với mã của tôi. varkhông phải là nguyên nhân, nó chỉ làm cho các triệu chứng có thể nhìn thấy. Đừng đổ lỗi cho người đưa tin.

Bây giờ, nhóm C # đã phát hành một hướng dẫn mã hóa chỉvar nên được sử dụng để nắm bắt kết quả của câu lệnh LINQ tạo ra một loại ẩn danh (vì ở đây, chúng tôi không có giải pháp thay thế thực sự ). Vâng, vít đó. Miễn là nhóm C # không cung cấp cho tôi một lập luận hợp lý cho hướng dẫn này, tôi sẽ bỏ qua nó bởi vì theo quan điểm chuyên môn và cá nhân của tôi, đó là baloney thuần túy. (Xin lỗi; tôi không có liên kết đến hướng dẫn trong câu hỏi.)var

Trên thực tế, có một số giải thích tốt (bề ngoài) về lý do tại sao bạn không nên sử dụng varnhưng tôi vẫn tin rằng chúng phần lớn sai. Lấy ví dụ về tìm kiếm và tìm kiếm trên mạng: tác giả tuyên bố rằng varviệc tìm kiếm địa điểm MyTypeđược sử dụng khó khăn . Đúng. Giao diện cũng vậy. Trên thực tế, tại sao tôi muốn biết lớp được sử dụng ở đâu? Tôi có thể quan tâm nhiều hơn đến nơi nó được khởi tạo và điều này vẫn có thể tìm kiếm được bởi vì ở đâu đó, hàm tạo của nó phải được gọi (ngay cả khi điều này được thực hiện gián tiếp, tên loại phải được đề cập ở đâu đó).


14
Trong bất kỳ IDE phong nha nào, bạn không sử dụng tìm kiếm văn bản để có được mức sử dụng lớp, bạn có IDE để thực hiện dựa trên cây phân tích của nó hoặc tuy nhiên, nó xác định các loại đối tượng. Vì chúng ta đang nói về việc gõ tĩnh, điều này sẽ tìm thấy mọi thứ trừ các loại ẩn danh.
quét bụi

6
Tôi không muốn kế thừa 100k dòng nguồn mà không có tài liệu và sử dụng var. Đặc biệt là nếu bạn kết hợp var với các tên biến ít hữu ích hơn. Tôi có thể thấy nó hữu ích khi minh họa một điểm (hoặc xử lý các loại ẩn danh) nhưng trong mã sản xuất?
Shea

7
Arnshea: bạn cũng đã chỉ ra vấn đề thực sự ở đó: tên biến vô dụng và tài liệu bị thiếu . Tôi thực sự không thấy những gì vargóp phần vào sự nhầm lẫn. Chắc chắn, có thể có trường hợp cần nhấn mạnh loại / kích thước của một biến (ví dụ: hoạt động bit mức thấp). Điều đó tốt: không ai từng tuyên bố rằng varnên được sử dụng riêng. Quy tắc rất đơn giản: nếu nó thực sự gây nhầm lẫn, đừng sử dụng nó.
Konrad Rudolph

17
Mọi ví dụ trái ngược với var tôi từng thấy đều cho rằng lập trình viên sẽ sử dụng các tên biến vô nghĩa. Nhưng có lẽ đây là lý do tại sao var tốt hơn là chỉ định rõ ràng một loại: Nó buộc lập trình viên phải đưa ra các tên biến tốt.
Ryan Lundy

16
Microsoft cũng gọi kiểu suy luận kiểu gõ vịt. - họ có thật không? Tôi sẽ bị sốc ...
Anton Tykhyy

118

Var, theo tôi, trong C # là một điều tốt tm . Bất kỳ biến nào được gõ vẫn được gõ mạnh, nhưng nó được loại từ phía bên phải của bài tập được xác định. Bởi vì thông tin loại có sẵn ở phía bên tay phải, trong hầu hết các trường hợp, không cần thiết và quá dài dòng cũng phải nhập thông tin ở phía bên trái. Tôi nghĩ rằng điều này làm tăng đáng kể khả năng đọc mà không giảm an toàn loại.

Từ quan điểm của tôi, sử dụng các quy ước đặt tên tốt cho các biến và phương thức là quan trọng hơn từ góc độ dễ đọc hơn thông tin loại rõ ràng. Nếu tôi cần thông tin loại, tôi luôn có thể di chuột qua biến (trong VS) và lấy nó. Nói chung, mặc dù, thông tin loại rõ ràng không cần thiết cho người đọc. Đối với nhà phát triển, trong VS bạn vẫn nhận được Intellisense, bất kể biến được khai báo như thế nào. Đã nói tất cả những điều đó, vẫn có thể có trường hợp tuyên bố rõ ràng kiểu này - có lẽ bạn có một phương thức trả về a List<T>, nhưng bạn muốn coi nó như mộtIEnumerable<T>trong phương pháp của bạn. Để đảm bảo rằng bạn đang sử dụng giao diện, việc khai báo biến của loại giao diện có thể làm cho điều này rõ ràng. Hoặc, có lẽ, bạn muốn khai báo một biến không có giá trị ban đầu - bởi vì nó ngay lập tức nhận được một giá trị dựa trên một số điều kiện. Trong trường hợp đó bạn cần loại. Nếu thông tin loại là hữu ích hoặc cần thiết, hãy tiếp tục và sử dụng nó. Mặc dù vậy, tôi cảm thấy rằng điều đó thường không cần thiết và mã dễ đọc hơn trong hầu hết các trường hợp.


3
Tôi đồng ý tổng thể. Điểm mấu chốt ở đây theo ý kiến ​​của tôi là chắc chắn rằng ý định đó là rõ ràng. Nếu nó không rõ ràng với các nhà phát triển đa số trong nhóm, thì nó gây bất lợi, không hữu ích. Điều đó nói rằng, cá nhân tôi là một fan cuồng nhiệt của điều này, nhưng đã phải kiềm chế bản thân một chút khi các nhà phát triển khác trong nhóm của tôi gặp khó khăn trong việc xác định ý định của tôi. Đi hình.
Steve Brouillard

3
Eh, tôi thấy nó dễ đọc hơn khi kiểu bên trái. Sử dụng ReSharper, tôi không phải gõ lại loại trên bất kỳ cách nào, vì vậy nó không làm phiền tôi.
BlueRaja - Daniel Pflughoeft

1
@BlueRaja - Tôi thấy rằng việc sử dụng tên biến tốt thường giúp loại bỏ sự cần thiết phải làm phiền với loại thực tế để hiểu. Intellisense vẫn có sẵn trên các biến được xác định "var", vì vậy tôi không cần biết loại để chọn phương thức / thuộc tính trên nó khi mã hóa.
tvanfosson

2
Nó không phải là quá nhiều về khi bạn đang mã hóa như khi bạn phải đọc mã.
BlueRaja - Daniel Pflughoeft

1
Sau đó, tôi phải ở bên dày, tôi cần phải có tên Phương thức và tên biến tốt sự hiểu biết về các loại đang được vận hành để có thể hiểu chính xác mã tôi đang đọc. Tôi nghĩ bạn đúng mặc dù đó là triệu chứng của những vấn đề lớn hơn. Một niềm tin. Để chắc chắn rằng mã đang làm những gì nó dường như đang làm, bạn cần chắc chắn về các loại đang được sử dụng.
AnthonyWJones

91

Cả hai điều đó đều hoàn toàn đúng; varcó thể có cả tác động tích cực và tiêu cực đến khả năng đọc. Theo tôi, varnên được sử dụng khi một trong những điều sau đây là đúng:

  1. Loại này là ẩn danh (tốt, bạn không có lựa chọn nào ở đây, vì nó phải là var trong trường hợp này)
  2. Kiểu này là rõ ràng dựa trên biểu thức được gán (tức là var foo = new TypeWithAReallyLongNameTheresNoSenseRepeating())

varkhông có tác động hiệu suất, vì nó là cú pháp đường; trình biên dịch nhập kiểu và định nghĩa nó một khi nó được biên dịch thành IL; không có gì thực sự năng động về nó.


1
đồng ý cả hai, mặc dù tôi có những hạn chế lâu dài đối với trường hợp thứ hai, nếu một loại dài như vậy thì nó thường là một loại chung có nhiều đối số chung được lồng vào nhau, trong trường hợp đó, một kiểu gõ "ShortType tương đương với TypeWithAReallyLongNameTheresNoSenseRepeat" có ý nghĩa hơn
Ion Todirel

12
Tôi không muốn bắt đầu một cuộc chiến tôn giáo, nhưng cá nhân tôi có xu hướng không đồng ý với Ion. Tôi rất thích một tên loại rất dài, nhưng rất chính xác (ala Chú Bob Martin) hơn là một tên loại ngắn hơn viết tắt và có thể mơ hồ. Tôi sẽ thêm lời cảnh báo mà tôi không đồng ý với việc làm tăng độ dài của tên một cách giả tạo. Nếu 5 ký tự tạo ra một tên ngắn gọn thể hiện rõ ý định, thì hãy sử dụng 5 chứ không phải 25.
Steve Brouillard

2
@Steve: Tôi phải đồng ý với bạn; tạo ra một "loại ngắn" (mà tôi cho rằng bạn có nghĩa là thừa kế từ loại chung chung cụ thể chỉ với mục đích rút ngắn tên) không phải là một cách làm tốt; nó sẽ yêu cầu bạn sao chép và chuyển qua bất kỳ hàm tạo nào từ kiểu chung, cũng như ngăn bạn chuyển một kiểu khác kế thừa từ kiểu chung sang hàm. Bạn đang sử dụng quyền thừa kế như typedefkhi không.
Adam Robinson

7
Sử dụng varkhi loại là rõ ràng? Có thể, nhưng lợi ích thực sự là khi loại không quan trọng. Nếu bạn đang làm những việc như thế var customers = whatever; var query = from c in customers select stuffthì không quan trọng loại 'khách hàng' chính xác là gì. Rõ ràng là làm thế nào bạn có thể sử dụng nó, và thế là đủ. Và nếu loại thực tế là cồng kềnh, đáng để loại bỏ nó.
Joren

2
@Kristoffer: Tôi có thể hiểu rằng muốn loại bỏ mớ hỗn độn của các thẻ, nhưng gói chúng vào một lớp không phải là (IMO) thay thế chấp nhận được, vì sau đó bạn loại bỏ khả năng bất kỳ lớp con (hợp pháp) nào khác thuộc loại chung đó một tham số hợp lệ. Tôi thà sử dụng một lệnh using ShortType = LongGenericType<A,B,C>ở đầu tệp, vì điều đó mang lại khả năng đọc giống nhau, không yêu cầu bạn tạo lại các hàm tạo và không loại bỏ các lớp con khỏi các ứng cử viên.
Adam Robinson

68

Từ Eric Lippert, một Kỹ sư thiết kế phần mềm cao cấp trong nhóm C #:

Tại sao vartừ khóa được giới thiệu?

Có hai lý do, một lý do tồn tại ngày nay, một lý do sẽ tăng lên trong 3.0.

Lý do đầu tiên là mã này cực kỳ xấu vì tất cả sự dư thừa:

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

Và đó là một ví dụ đơn giản - tôi đã viết tệ hơn. Bất cứ khi nào bạn buộc phải nhập chính xác cùng một thứ hai lần, đó là sự dư thừa mà chúng ta có thể loại bỏ. Viết đẹp hơn nhiều

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

và để trình biên dịch tìm ra loại dựa trên sự phân công.

Thứ hai, C # 3.0 giới thiệu các loại ẩn danh. Vì các loại ẩn danh theo định nghĩa không có tên, bạn cần có thể suy ra loại biến từ biểu thức khởi tạo nếu loại của nó là ẩn danh.

Nhấn mạnh mỏ. Toàn bộ bài viết, C # 3.0 vẫn được gõ tĩnh, trung thực! , và loạt tiếp theo là khá tốt.

Đây là những gì vardành cho. Các ứng dụng khác có thể sẽ không hoạt động tốt. Bất kỳ so sánh với JScript, VBScript hoặc gõ động là tổng số bunk. Lưu ý một lần nữa, varbắt buộc để có một số tính năng khác hoạt động trong .NET.


Tôi thấy lập luận của Lippert thật kỳ quặc. Không ai gõ tên lớp thứ hai, họ để Intellisense viết nó cho họ, nhưng sau đó anh ta quay lại và tuyên bố rằng var tốt hơn vì trình biên dịch / Intellisense xử lý nó. Bạn có thể có nó trong cả hai cách!
Dave

5
Nhóm C # không kiểm soát intellisense, họ kiểm soát trình biên dịch. Trong mọi trường hợp đó không phải là vấn đề chính. Tôi không nghĩ var sẽ kiếm được 100 điểm khi lưu gõ một mình.
Dustman

@Dustman: var hoàn toàn không lưu gõ. Nó làm cho bạn viết nhiều hơn!
Piotr Perak

53

Tôi nghĩ rằng việc sử dụng var nên được kết hợp với các tên biến được chọn một cách khôn ngoan.

Tôi không có vấn đề gì khi sử dụng var trong một tuyên bố foreach, miễn là nó không như thế này:

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

Nếu nó giống như thế này:

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

... sau đó ai đó đọc mã sẽ có nhiều khả năng hiểu "danh sách" là gì. Nếu bạn có quyền kiểm soát tên của biến danh sách, điều đó thậm chí còn tốt hơn.

Điều tương tự có thể áp dụng cho các tình huống khác. Điều này khá vô dụng:

var x = SaveFoo(foo);

... nhưng điều này có ý nghĩa:

var saveSucceeded = SaveFoo(foo);

Mỗi người để riêng mình, tôi đoán. Tôi đã thấy mình làm điều này, điều đó thật điên rồ:

var f = (float)3;

Tôi cần một số loại chương trình var 12 bước. Tên tôi là Matt và tôi (ab) sử dụng var.


6
Vâng, điều duy nhất sai với "var f = (float) 3;" là nó phải là "var f = 3f" hoặc "var f = 3.0 (gây ra độ chính xác đơn hút)".
MichaelGG

3
Heh yeah 3f hoặc 3.0 là con đường để đi! Chúng tôi var maniacs phải gắn bó với nhau!
Matt Hamilton

27
Vấn đề thực sự trong ví dụ đầu tiên đó là "danh sách", không phải "c". "Danh sách" của cái gì ? "Danh sách" nên được đổi tên thành "khách hàng" hoặc "khách hàngWhoOweMoney" hoặc "khách hàng hiện tại" hoặc một cái gì đó mô tả hơn nhiều. Và một khi bạn có được điều đó, "c" có thể giữ nguyên trạng, bởi vì bạn đã biết nó sẽ chứa gì.
Ryan Lundy

4
Chào Matt! Tên tôi là Kenny và tôi là một varaddict.
kenny

var Matt Hamil = "Luke Skywalker"; // tước một tấn ra khỏi nó
Binoj Antony

40

Chúng tôi đã áp dụng ethos "Mã cho mọi người, không phải máy móc", dựa trên giả định rằng bạn dành nhiều thời gian hơn trong chế độ bảo trì nhiều lần so với phát triển mới.

Đối với tôi, điều đó loại trừ đối số mà trình biên dịch "biết" loại biến là gì - chắc chắn, bạn không thể viết mã không hợp lệ ngay lần đầu tiên vì trình biên dịch ngăn mã của bạn biên dịch, nhưng khi nhà phát triển tiếp theo đang đọc mã trong 6 tháng thời gian họ cần có thể suy ra những gì biến đang làm đúng hoặc không chính xác và nhanh chóng xác định nguyên nhân của các vấn đề.

Như vậy

var something = SomeMethod();

bị đặt ra ngoài vòng pháp luật bởi các tiêu chuẩn mã hóa của chúng tôi, nhưng những điều sau đây được khuyến khích trong nhóm của chúng tôi vì nó làm tăng khả năng đọc:

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

4
Tôi đã thấy rằng ("Mã cho mọi người, không phải máy móc") là một hướng dẫn tuyệt vời - làm theo nó có thể dẫn đến mã tốt hơn và giúp tránh tối ưu hóa sớm.
Thanatos

3
Tôi không nhận được danh sách var = new KeyValuePair <chuỗi, double>? Đối với tôi một danh sách có thể có nhiều hơn về điều.
TTT

"Mã cho người, không phải máy móc" - amen.
dùng1068352

39

Nó không tệ, nó là một thứ phong cách, có xu hướng chủ quan. Nó có thể thêm sự không nhất quán, khi bạn sử dụng var và khi bạn không sử dụng.

Một trường hợp đáng quan tâm khác, trong cuộc gọi sau, bạn không thể biết chỉ bằng cách xem mã loại được trả về bởi CallMe:

var variable = CallMe();

Đó là khiếu nại chính của tôi chống lại var.

Tôi sử dụng var khi tôi khai báo các đại biểu ẩn danh trong các phương thức, bằng cách nào đó var trông sạch hơn so với khi tôi sử dụng Func. Xem xét mã này:

var callback = new Func<IntPtr, bool>(delegate(IntPtr hWnd) {
   ...
});

EDIT : Cập nhật mẫu mã cuối cùng dựa trên đầu vào của Julian


3
Nhưng bạn có thực sự cần phải biết loại ngay tại dòng đó không? Bạn biết rằng CallMe trả về một cái gì đó; không đủ để biết rằng một biến cục bộ có tên variableđược tạo ra? Trừ khi bạn mở rộng ví dụ của mình, đây không phải là một khiếu nại rất chắc chắn, IMO.
Randolpho

2
Không phải là không dài dòng, mà là không để trình biên dịch thực hiện cú pháp đường cho bạn. Hãy xem xét điều này: var getter ..., bây giờ Func <object> getter này ..., với lần thứ hai bạn biết bạn không phải cung cấp bất kỳ tham số nào và những gì nó trả về. Bạn biết ngay từ đầu "phải làm gì" và có thể đưa ra quyết định nhanh hơn, khi thiết kế một cái gì đó hoặc tái cấu trúc. Có tất cả các thông tin trong tay là quan trọng hơn một vài nhân vật. Điều này chỉ có thể được đánh giá cao khi bạn làm việc với nhiều mã.
Ion Todirel

2
Vì tất cả chúng ta đều đang nói về studio hình ảnh, dù sao thì việc di chuột qua biến số trong một giây và xem chỉ là loại gì? Dù sao cũng tốt hơn là chạy đến khai báo.
Rubys

3
Tên chung và tên hàm ( variable, CallMe) tạo ra các ví dụ xấu. Tuy nhiên, nếu CallMe()là một chức năng trong một loại "ứng dụng điện thoại" nào đó, thì var call = CallMe(); .... call.HangUp();sẽ có ý nghĩa hơn nhiều.
Danko Durbić

3
@Randolpho: "vấn đề lớn là gì khi di chuột qua biến trong một giây và chỉ xem đó là loại gì?" Nó thêm thời gian vào chi phí bảo trì ... cộng thêm một giây chỉ là thời gian di chuột thay vì đếm bàn phím để chuyển đổi ngữ cảnh chuột. Tôi không biết về bạn, nhưng tôi làm việc với thời hạn. Mỗi lần tôi phải di chuột qua một biến để tìm ra nó là loại gì, đó là thời gian mà tôi có thể dành thời gian để khắc phục một vấn đề tốt hơn.
Powerlord

36

Var không giống như biến thể chút nào. Biến vẫn được gõ mạnh, chỉ là bạn không nhấn phím để hiểu theo cách đó. Bạn có thể di chuột qua nó trong Visual Studio để xem loại. Nếu bạn đang đọc mã in, có thể bạn phải suy nghĩ một chút để biết loại này là gì. Nhưng chỉ có một dòng khai báo nó và nhiều dòng sử dụng nó, vì vậy việc đặt tên cho những thứ đàng hoàng vẫn là cách tốt nhất để làm cho mã của bạn dễ theo dõi hơn.

Là sử dụng Intellisense lười biếng? Nó ít gõ hơn toàn bộ tên. Hoặc có những thứ ít làm việc hơn nhưng không đáng bị chỉ trích? Tôi nghĩ là có, và var là một trong số đó.


6
+1, chỉ người cần lưu ý rằng varkhông có gì để làm Variant.
dùng7116

27

Thời gian rất có thể bạn sẽ cần điều này là cho các loại ẩn danh (trong đó yêu cầu 100%); nhưng nó cũng tránh sự lặp lại cho các trường hợp tầm thường và IMO làm cho dòng rõ ràng hơn. Tôi không cần phải xem loại hai lần để khởi tạo đơn giản.

Ví dụ:

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

(vui lòng không chỉnh sửa hscroll ở trên - điều này chứng tỏ quan điểm !!!)

vs

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

Tuy nhiên, có những trường hợp khi điều này gây hiểu lầm và có khả năng gây ra lỗi. Hãy cẩn thận varkhi sử dụng nếu biến ban đầu và loại khởi tạo không giống nhau. Ví dụ:

static void DoSomething(IFoo foo) {Console.WriteLine("working happily") }
static void DoSomething(Foo foo) {Console.WriteLine("formatting hard disk...");}

// this working code...
IFoo oldCode = new Foo();
DoSomething(oldCode);
// ...is **very** different to this code
var newCode = new Foo();
DoSomething(newCode);

1
(để biết thông tin, bạn có thể gặp các vấn đề tương tự đối với bất kỳ điều gì trong đó đây là chuyển đổi loại ngầm)
Marc Gravell

1
Không đồng ý với phần mà bạn không muốn thấy nó hai lần trong cùng một dòng. Có thể trong tương lai bạn không trực tiếp tạo biến sau khi khai báo (ví dụ: nếu dưới định nghĩa) thì có thể không trực tiếp rõ loại này là gì. Hầu hết các nhà phát triển được sử dụng để xem loại trực tiếp ở đầu dòng, đặc biệt là trong mã phức tạp, bạn không muốn làm cho việc đọc mã trở nên khó khăn hơn.
Gertjan

@TheVillageIdiot - Tôi đã khôi phục lại bản chỉnh sửa của bạn, vì nhân dịp này , hscroll có liên quan đến điểm ;-p
Marc Gravell

2
@Gertjan - bộ não của tôi bị hạn chế; nếu nó phức tạp, tôi không muốn nhìn thấy nó hai lần và phải bắt đầu so sánh (giao diện / cụ thể / vv). Tôi rất vui khi thấy nó một lần và nghĩ rằng "gõ như một trong số họ".
Marc Gravell

17

Một trường hợp cụ thể mà var rất khó: đánh giá mã ngoại tuyến, đặc biệt là những đánh giá được thực hiện trên giấy.

Bạn không thể dựa vào chuột cho điều đó.


17
Tại sao bạn đang xem lại mã trên giấy? Hãy nghĩ về những cái cây! ;)
quét bụi

8
Bạn có thể có cùng một vấn đề mà không cần sử dụng var. Vấn đề không phải là var; vấn đề là tên biến xấu. Nếu tên biến được chọn tốt, việc sử dụng var không thành vấn đề.
Ryan Lundy

Tôi có một anh chàng trong nhóm của tôi xem xét mã của riêng anh ta và tìm lỗi, bằng cách in mã của anh ta. Những bức tường của anh ấy được bao phủ với mã. Có lần tôi bước vào và anh ta có cả một bảng trắng lớn được bao phủ bởi một bài tập sửa lỗi. Có lẽ là ~ 10000 LỘC
bíp bíp

Tên biến một mình không giải quyết được vấn đề trừ khi bạn quay lại ký hiệu của Lynn trong đó loại là một phần của tên.
Kevin Gale

17

Tôi không thấy vấn đề lớn là gì ..

var something = someMethod(); // Type of 'something' not clear <-- not to the compiler!

Bạn vẫn có đầy đủ thông tin về 'một cái gì đó', và đối với bất kỳ trường hợp mơ hồ nào, bạn có bài kiểm tra đơn vị của mình, phải không? (phải không?)

Nó không phải là varchar, nó không mờ và chắc chắn nó không phải là kiểu gõ động hay yếu. Nó đang dừng maddnes như thế này:

List<somethinglongtypename> v = new List<somethinglongtypename>();

và giảm tổng số suy nghĩ đó xuống:

var v = new List<somethinglongtypename>();

Đẹp, không đẹp bằng:

v = List<somethinglongtypename>();

Nhưng đó là những gì Boo dành cho.


Kiểu 'cái gì đó' rất rõ ràng đối với trình biên dịch, bên trong, "var" được đặt thành kiểu trả về của 'someMethod', nó rõ ràng đối với trình biên dịch, nhưng có thể không rõ ràng đối với các nhà phát triển làm việc trong dự án. và Boo đang lớn lên trong tôi nhanh chóng.
stephenbayer

Không, v = List<somethinglongtypename>();thậm chí còn không đẹp hơn. Điều quan trọng là phải phân biệt giữa việc giới thiệu một biến mới và gán cho một biến hiện có.
HighCommander4

Chà, nếu bạn đã được gán cho 'v' trước trong phạm vi hiện tại, thì đó là gán cho một hiện có. Mặt khác, nó được gán cho biến mới 'v'. Dễ dàng.
Frep D-Oronge

17

Nếu ai đó đang sử dụng vartừ khóa vì họ không muốn "tìm ra loại", đó chắc chắn là lý do sai. Cácvar từ khóa không tạo ra một biến với một loại năng động, trình biên dịch vẫn phải biết loại. Vì biến luôn có một loại cụ thể, nên loại này cũng được hiển thị trong mã nếu có thể.

Những lý do tốt để sử dụng vartừ khóa là ví dụ:

  • Khi cần, nghĩa là khai báo một tham chiếu cho một loại ẩn danh.
  • Trong đó nó làm cho mã dễ đọc hơn, tức là loại bỏ các khai báo lặp lại.

Viết ra kiểu dữ liệu thường làm cho mã dễ theo dõi hơn. Nó hiển thị loại dữ liệu bạn đang sử dụng, do đó bạn không phải tìm ra loại dữ liệu bằng cách đầu tiên tìm ra mã này làm gì.


11

Hiện tại Intellisense mạnh đến mức nào, tôi không chắc var khó đọc hơn việc có các biến thành viên trong một lớp hay các biến cục bộ trong một phương thức được xác định ngoài vùng màn hình hiển thị.

Nếu bạn có một dòng mã như

IDictionary<BigClassName, SomeOtherBigClassName> nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Là dễ dàng hơn hoặc khó đọc hơn:

var nameDictionary = new Dictionary<BigClassName, SomeOtherBigClassName>();

Tôi đã không thực sự xem xét điều này, dường như từ một câu hỏi khác là một điểm khá mạnh đối với một lần khác để sử dụng nó.
Fingerlas

Về cơ bản đó là lý do duy nhất họ triển khai nó (ngoài việc có thể khai báo các loại ẩn danh, nhưng họ có thể đã tạo "var" một từ khóa đặc biệt chỉ dành cho các loại ẩn danh.)
mqp

10

Tôi nghĩ điều quan trọng với VAR là chỉ sử dụng nó khi thích hợp tức là khi thực hiện mọi thứ trong Linq mà nó tạo điều kiện (và có thể trong các trường hợp khác).

Nếu bạn một loại cho một cái gì đó thì bạn nên sử dụng nó - không nên làm như vậy là sự lười biếng đơn giản (trái ngược với sự lười biếng sáng tạo thường được khuyến khích - các lập trình viên giỏi thường rất khó để lười biếng và có thể được xem xét nguồn gốc của sự vật ở nơi đầu tiên).

Lệnh cấm chăn cũng tệ như lạm dụng cấu trúc ở nơi đầu tiên nhưng cần phải có một tiêu chuẩn mã hóa hợp lý.

Một điều khác cần nhớ là nó không phải là một kiểu var VB trong đó nó không thể thay đổi các loại - đó một biến được gõ mạnh, chỉ là loại được suy ra (đó là lý do tại sao có những người sẽ cho rằng nó không hợp lý với sử dụng nó trong giả sử, nhưng tôi không đồng ý vì lý do cả khả năng đọc và khả năng bảo trì).

Tôi nghi ngờ cái này sẽ chạy và chạy (-:

Murph


10

Chắc chắn, intlà dễ dàng, nhưng khi kiểu của biến là IEnumerable<MyStupidLongNamedGenericClass<int, string>>, var làm cho mọi thứ dễ dàng hơn nhiều.


2
+1 cho điều này. intso với varlà một cái gì đó để cãi nhau, nhưng nhiều loại chung lồng nhau tạo ra varmột ơn trời. Đây là nơi sử dụng tên loại nhiều lần thực sự phá hủy khả năng đọc của mã.
Nông dân Chris

Đây hoàn toàn là lý do sai lầm khi sử dụng nó. Nếu mã của bạn sử dụng một kiểu chung lồng nhau, bạn nên lấy một lớp có tên cụ thể cho nó. Ví dụ: class IntStringEnumerator : IEnumerable<MyStupidLongNamedGenericClass<int, string>>và sau đó sử dụng tên mới. Điều đó làm sạch mã và mô tả các loại tốt hơn.
xxbbcc

Được rồi, nhưng ví dụ của tôi chỉ là cường điệu. IntStringEnumerator i = new IntStringEnumerator()vẫn còn quá nhiều đánh máy.
Blorgbeard sẽ ra vào

9

Bị đánh cắp từ bài đăng về vấn đề này tại CodingHorror :


Thật không may, bạn và những người khác khá nhiều đã hiểu sai. Mặc dù tôi đồng ý với bạn rằng sự dư thừa không phải là một điều tốt, nhưng cách tốt hơn để giải quyết vấn đề này sẽ là làm một việc như sau:

MyObject m = new ();

Hoặc nếu bạn đang truyền tham số:

Người p = new ("FirstName", "LastName);

Trong trường hợp tạo một đối tượng mới, trình biên dịch sẽ nhập kiểu từ phía bên trái chứ không phải bên phải. Điều này có những ưu điểm khác so với "var", ở chỗ nó cũng có thể được sử dụng trong khai báo trường (cũng có một số lĩnh vực khác cũng có thể hữu ích, nhưng tôi sẽ không tham gia vào đây).

Cuối cùng, nó không nhằm giảm sự dư thừa. Đừng hiểu sai ý tôi, "var" rất RẤT quan trọng trong C # đối với các loại / phép chiếu ẩn danh, nhưng việc sử dụng ở đây chỉ là CÁCH (và tôi đã nói điều này trong một thời gian dài) khi bạn làm xáo trộn loại đó đang được sử dụng. Phải gõ hai lần là quá thường xuyên, nhưng khai báo bằng 0 lần là quá ít.

Nicholas Paldino .NET / C # MVP vào ngày 20 tháng 6 năm 2008 08:00 AM


Tôi đoán nếu mối quan tâm chính của bạn là phải gõ ít hơn - thì sẽ không có bất kỳ đối số nào sẽ khiến bạn sử dụng nó.

Nếu bạn chỉ sẽ bao giờ có người nhìn vào mã của bạn, sau đó ai quan tâm? Mặt khác, trong trường hợp như thế này:

var people = Managers.People

không sao, nhưng trong trường hợp như thế này:

var fc = Factory.Run();

nó làm chập mạch mọi kiểu khấu trừ tức thời mà não tôi có thể bắt đầu hình thành từ 'tiếng Anh' của mã.

Mặt khác, chỉ cần sử dụng phán đoán và lập trình 'lịch sự' tốt nhất của bạn đối với những người khác có thể phải làm việc trong dự án của bạn.


4
Các ví dụ của bạn ở trên không phải là một đối số cho việc không sử dụng var; chúng là một đối số để sử dụng tên biến mô tả tốt. Nếu, thay vì [var fc = Factory.Run ();] bạn đã có [bool fc = Factory.Run ();], mã sẽ không trở nên rõ ràng hơn.
Ryan Lundy

9

Sử dụng varthay vì loại rõ ràng làm cho tái cấu trúc dễ dàng hơn nhiều (do đó tôi phải mâu thuẫn với các áp phích trước đó có nghĩa là nó không có sự khác biệt hoặc nó hoàn toàn là "đường cú pháp").

Bạn có thể thay đổi kiểu trả về của các phương thức của bạn mà không thay đổi mọi tệp nơi phương thức này được gọi. Hãy tưởng tượng

...
List<MyClass> SomeMethod() { ... }
...

được sử dụng như

...
IList<MyClass> list = obj.SomeMethod();
foreach (MyClass c in list)
  System.Console.WriteLine(c.ToString());
...

Nếu bạn muốn cấu trúc lại SomeMethod()để trả về một IEnumerable<MySecondClass>, bạn sẽ phải thay đổi khai báo biến (cũng bên trongforeach ) ở mọi nơi bạn đã sử dụng phương thức.

Nếu bạn viết

...
var list = obj.SomeMethod();
foreach (var element in list)
  System.Console.WriteLine(element.ToString());
...

thay vào đó, bạn không phải thay đổi nó.


đồng ý - tự hỏi tại sao tác dụng phụ tốt đẹp này không được chào hàng nhiều như một số ưu điểm khác, chủ quan hơn trong các phản ứng phổ biến hơn.
fieldingmellish

Nó hapen với tôi ngày hôm nay. Tôi có một lớp nhà máy trả về istance của một lớp MainMothy. Hôm nay tôi đã tạo ra một MainMothy2 với cùng giao diện của MainMothy. Tôi có tất cả mã ứng dụng của tôi chưa được xử lý sau khi thay đổi!
Marco Staffoli

8

@aku: Một ví dụ là đánh giá mã. Một ví dụ khác là tái cấu trúc các kịch bản.

Về cơ bản, tôi không muốn đi săn bằng chuột. Nó có thể không có sẵn.


2
Thật thú vị khi bạn nói rằng vì var có thể làm cho việc tái cấu trúc đơn giản hơn. Nếu bạn đã sử dụng var, bạn không cần phải làm vậy. Bây giờ bạn luôn có thể dựa vào các công cụ tái cấu trúc của IDE, nhưng bạn biết đấy, bạn luôn có thể dựa vào IDE cho loại đó :)
Fred

8

Đó là một vấn đề của hương vị. Tất cả sự ồn ào này về loại biến sẽ biến mất khi bạn quen với các ngôn ngữ được gõ động. Đó là, nếu bạn đã từng bắt đầu thích chúng (Tôi không chắc mọi người có làm được không, nhưng tôi thì có).

C # 's varkhá thú vị ở chỗ nó trông giống như gõ động, nhưng thực sự là gõ tĩnh - trình biên dịch thực thi đúng cách sử dụng.

Loại biến của bạn không thực sự quan trọng (điều này đã được nói trước đây). Nó phải tương đối rõ ràng từ ngữ cảnh (tương tác của nó với các biến và phương thức khác) và tên của nó - đừng mong đợi danh sách khách hàng có chứa một int...

Tôi vẫn đang chờ xem ông chủ của tôi nghĩ gì về vấn đề này - tôi đã lấy một chiếc chăn "đi trước" để sử dụng bất kỳ cấu trúc mới nào trong 3.5, nhưng chúng tôi sẽ làm gì về bảo trì?


7

Trong so sánh giữa bạn IEnumerable<int>IEnumerable<double>bạn không cần phải lo lắng - nếu bạn chuyển sai loại, mã của bạn sẽ không được biên dịch.

Không có mối quan tâm về loại an toàn, như varkhông năng động. Đó chỉ là ma thuật biên dịch và bất kỳ loại cuộc gọi không an toàn nào bạn thực hiện sẽ bị bắt.

Var là hoàn toàn cần thiết cho Linq:

var anonEnumeration =
    from post in AllPosts()
    where post.Date > oldDate
    let author = GetAuthor( post.AuthorId )
    select new { 
        PostName = post.Name, 
        post.Date, 
        AuthorName = author.Name
    };

Bây giờ hãy nhìn vào anonEnumutions trong intellisense và nó sẽ xuất hiện một cái gì đó nhưIEnumerable<'a>

foreach( var item in anonEnumeration ) 
{
    //VS knows the type
    item.PostName; //you'll get intellisense here

    //you still have type safety
    item.ItemId;   //will throw a compiler exception
}

Trình biên dịch C # khá thông minh - các loại anon được tạo riêng sẽ có cùng loại được tạo nếu thuộc tính của chúng khớp.

Bên ngoài đó, miễn là bạn có intellisense, nó có ý nghĩa tốt để sử dụng varbất cứ nơi nào bối cảnh rõ ràng.

//less typing, this is good
var myList = new List<UnreasonablyLongClassName>();

//also good - I can't be mistaken on type
var anotherList = GetAllOfSomeItem();

//but not here - probably best to leave single value types declared
var decimalNum = 123.456m;

Hãy bỏ đi IQueriable<T>trước khi lặp đi lặp lại: anonEnumeration.ToList();
David Diez

@DavidDiez bạn có thể viết lại? Tuyên bố của bạn không có ý nghĩa. Không có đoạn mã nào của tôi tham chiếu IQueryablehoặc.ToList()
Keith

var anonEnumeration = from post in AllPosts() where post.Date > oldDate let author = GetAuthor( post.AuthorId ) select new { PostName = post.Name, post.Date, AuthorName = author.Name };không trả lại một IQueriable<T>?
David Diez

1
@DavidDiez nó phụ thuộc vào những gì AllPosts()trả về - người hỏi đề cập đến List<T>vì vậy tôi giả định rằng. Trong trường hợp đó, kết quả là anonEnumerationloại IEnumerable<'a>. Bây giờ nếu AllPosts()trả về IQueryable<T>thay vào đó anonEnumerationsẽ trở thành IQueryable<'a>(lưu ý không itrong Truy vấn) - tuy nhiên trong trường hợp đó, mã của tôi vẫn hoạt động vì IQueryable<T>thực hiện IEnumerable<T>. Có rất nhiều câu hỏi và trả lời hay hơn ở đây về sự khác biệt giữa chúng - ở đây trường hợp của tôi 'alà ẩn danh và varcho phép bạn gán nó cho một biến được gõ tĩnh.
Keith

Ồ tôi hiểu rồi, cảm ơn vì đã giải thích nó :) Nhận xét của tôi là bởi vì lặp đi lặp lại IQueryable<T>không phải là một cách thực hành tốt bởi vì trong mỗi lần lặp lại, bạn đang thực hiện một câu lệnh đọc trong DB. Hãy chắc chắn *.ToList() IQueryable<T>trước khi lặp lại chúng
David Diez

7

Tôi đoán nó phụ thuộc vào quan điểm của bạn. Cá nhân tôi chưa bao giờ gặp khó khăn khi hiểu một đoạn mã vì var"sử dụng sai" và đồng nghiệp của tôi và tôi sử dụng nó khá nhiều. (Tôi đồng ý rằng Intellisense là một trợ giúp rất lớn trong vấn đề này.) Tôi hoan nghênh nó như là một cách để loại bỏ hành trình lặp đi lặp lại.

Rốt cuộc, nếu tuyên bố như

var index = 5; // this is supposed to be bad

var firstEligibleObject = FetchSomething(); // oh no what type is it
                                            // i am going to die if i don't know

thực sự là không thể đối phó, không ai sẽ sử dụng các ngôn ngữ được gõ động.


Có lẽ trong .Net 4 nơi các loại động là vị trí phổ biến, điều này sẽ trở nên quan trọng hơn?
Colin Desmond

2
Ngược lại, nếu bây giờ bạn bị nhầm lẫn bởi "var", tôi sẽ hy vọng rằng bạn sẽ bị nhầm lẫn thêm bởi "động". Chúa cấm bất cứ ai từng tuyên bố một động lực và sau đó tạo một tham chiếu đến nó bằng cách sử dụng "var" :)
mqp

Ý tôi là một cái gì đó như động d = 52; var x = d; mà nên ổn
mqp

7

Tôi chỉ sử dụng var khi nó rõ ràng để xem loại nào được sử dụng.

Ví dụ: tôi sẽ sử dụng var trong trường hợp này, bởi vì bạn có thể thấy ngay rằng x sẽ thuộc loại "MyClass":

var x = new MyClass();

Tôi sẽ KHÔNG sử dụng var trong các trường hợp như thế này, vì bạn phải kéo chuột qua mã và nhìn vào tooltip để xem loại MyFactor trả về loại nào:

var x = MyClass.MyFunction();

Đặc biệt, tôi không bao giờ sử dụng var trong trường hợp phía bên phải thậm chí không phải là một phương thức, mà chỉ là một giá trị:

var x = 5;

(vì trình biên dịch không thể biết nếu tôi muốn một byte, short, int hay gì nữa)


Nếu phía bên tay phải không đủ rõ ràng để biện minh cho việc sử dụng var, thì đó varkhông phải là vấn đề: phía bên phải là vấn đề. Nó không đủ để mô tả . Customer c = GetContext()vẫn chưa rõ ràng và không có tốt hơn so với sử dụng var.
JulianR

6

Đối với tôi, ác cảm đối với việc varminh họa tại sao song ngữ trong .NET lại quan trọng. Đối với những lập trình viên C # cũng đã thực hiện VB .NET, những lợi thế của vartrực giác là rõ ràng. Khai báo C # tiêu chuẩn của:

List<string> whatever = new List<string>();

là tương đương, trong VB .NET, khi gõ này:

Dim whatever As List(Of String) = New List(Of String)

Không ai làm điều đó trong VB .NET. Sẽ thật ngớ ngẩn, bởi vì phiên bản .NET đầu tiên bạn đã có thể làm điều này ...

Dim whatever As New List(Of String)

... Nó tạo ra biến và khởi tạo tất cả trong một dòng nhỏ gọn hợp lý. Ah, nhưng nếu bạn muốn một IList<string>, không phải là một List<string>? Chà, trong VB .NET có nghĩa là bạn phải làm điều này:

Dim whatever As IList(Of String) = New List(Of String)

Giống như bạn phải làm trong C # và rõ ràng không thể sử dụng varcho:

IList<string> whatever = new List<string>();

Nếu bạn cần loại là một cái gì đó khác nhau, nó có thể được. Nhưng một trong những nguyên tắc cơ bản của lập trình tốt là giảm sự dư thừa, và đó chính xác là những gì var làm.


1
Thật buồn cười khi bạn đề cập đến song ngữ như một cái gì đó thúc đẩy việc sử dụng var. Sự đối nghịch của tôi đối với từ khóa var bắt nguồn trực tiếp từ sự lưu loát của tôi trong javascript! :)
urig

vartrong C # không có kết nối nào với varJavaScript. Một varbiến -declared trong C # được gõ mạnh.
Ryan Lundy

6

Sử dụng nó cho các loại ẩn danh - đó là những gì nó có. Bất cứ điều gì khác là sử dụng quá xa. Giống như nhiều người lớn lên trên C, tôi thường nhìn vào bên trái của tờ khai cho loại. Tôi không nhìn vào phía bên phải trừ khi tôi phải làm thế. Sử dụng varcho bất kỳ tuyên bố cũ nào khiến tôi làm điều đó mọi lúc, điều mà cá nhân tôi thấy không thoải mái.

Những người nói rằng 'không thành vấn đề, hãy sử dụng những gì bạn hài lòng' sẽ không nhìn thấy toàn bộ bức tranh. Mọi người sẽ nhận mã của người khác vào lúc này hay lúc khác và phải đối phó với bất kỳ quyết định nào họ đưa ra tại thời điểm họ viết nó. Thật tệ khi phải đối phó với các quy ước đặt tên hoàn toàn khác nhau, hoặc - kiểu kẹp cổ điển - kiểu giằng, mà không thêm toàn bộ điều ' varhoặc không' vào hỗn hợp. Trường hợp xấu nhất sẽ là nơi một lập trình viên không sử dụng varvà sau đó là một người bảo trì yêu thích nó và mở rộng mã sử dụng nó. Vì vậy, bây giờ bạn có một mớ hỗn độn không lành mạnh.

Các tiêu chuẩn là một điều tốt chính xác bởi vì chúng có nghĩa là bạn có nhiều khả năng có thể nhận mã ngẫu nhiên và có thể mò mẫm nó một cách nhanh chóng. Càng nhiều thứ khác biệt, càng khó. Và việc chuyển sang phong cách 'var ở mọi nơi' tạo nên sự khác biệt lớn .

Tôi không ngại gõ động, và tôi không ngại gõ phím - trong các ngôn ngữ được thiết kế cho chúng. Tôi khá thích Python. Nhưng C # được thiết kế như một ngôn ngữ được gõ rõ ràng tĩnh và đó là cách nó nên tồn tại. Phá vỡ các quy tắc cho các loại ẩn danh là đủ xấu; cho phép mọi người tiếp tục phát triển hơn nữa và phá vỡ các thành ngữ của ngôn ngữ hơn nữa là điều tôi không hài lòng. Bây giờ vị thần đã ra khỏi chai, nó sẽ không bao giờ quay trở lại. C # sẽ bị balkan thành trại. Không tốt.


7
Ồ Bỏ qua tất cả các đối số được đưa ra trong chủ đề này cho đến nay và thiết lập lại toàn bộ cuộc thảo luận là một thành tựu.
Konrad Rudolph

100% này mô tả cách tôi cảm nhận về 'var', đặc biệt từ quan điểm chọn mã của ai đó. Việc sử dụng var hoàn toàn thay đổi nhiệm vụ trong tầm tay nếu nó bị vấy bẩn trong suốt. +1
Simon

6

Nhiều lần trong quá trình thử nghiệm, tôi thấy mình có mã như thế này:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();
Console.WriteLine(something);

Bây giờ, đôi khi, tôi sẽ muốn xem một số thứ mà chính nó chứa, một số khác không phải là loại mà CallMethod () trả về. Vì tôi đang sử dụng var, nên tôi chỉ thay đổi điều này:

var something = myObject.SomeProperty.SomeOtherThing.CallMethod();

đến đây:

var something = myObject.SomeProperty.SomeOtherThing;

Nếu không có var, tôi cũng phải tiếp tục thay đổi kiểu khai báo ở phía bên trái. Tôi biết nó là nhỏ, nhưng nó cực kỳ thuận tiện.


6

Đối với các afficionados nghĩ rằng vartiết kiệm thời gian, cần ít thao tác gõ phím hơn:

StringBuilder sb = new StringBuilder();

hơn

var sb = new StringBuilder();

Đếm em nếu em không tin anh ...

19 so với 21

Tôi sẽ giải thích nếu tôi phải, nhưng chỉ cần thử nó ... (tùy thuộc vào trạng thái hiện tại của bạn, bạn có thể phải nhập thêm một vài cho mỗi người)

Và nó đúng với mọi loại bạn có thể nghĩ đến !!

Cảm nhận cá nhân của tôi là var không bao giờ nên được sử dụng trừ trường hợp không biết loại này vì nó làm giảm khả năng đọc nhận dạng trong mã. Bộ não mất nhiều thời gian hơn để nhận ra loại hơn là một dòng đầy đủ. Đồng hồ cũ, những người hiểu mã máy và bit biết chính xác những gì tôi đang nói. Bộ não xử lý song song và khi bạn sử dụng var, bạn buộc nó phải tuần tự hóa đầu vào của nó. Tại sao bất cứ ai cũng muốn làm cho bộ não của họ làm việc chăm chỉ hơn? Đó là những gì máy tính dành cho.


Tôi thấy sự lặp lại của stringBuilder sb = new StringBuilder () lộn xộn và lâu hơn để nhận ra rõ ràng. Đó là tiếng ồn thêm. Vấn đề là, xác định những gì không và không tạo thành nỗ lực trí tuệ thêm để hiểu một số mã là khá chủ quan!
LJS

"var không bao giờ nên được sử dụng trừ trường hợp không biết loại ..." - Bạn có thể LUÔN biết loại, cũng như trình biên dịch. Đây không phải là kiểu gõ động, nó chỉ cho phép trình biên dịch xác định loại cho bạn. Nhưng loại không bao giờ là một ẩn số.
Gabriel Magana

5

Tôi chia var ở khắp mọi nơi, những nơi đáng nghi duy nhất đối với tôi là các loại ngắn nội bộ, ví dụ: tôi thích int i = 3;hơnvar i = 3;


5

Nó chắc chắn có thể làm cho mọi thứ đơn giản hơn, từ mã tôi đã viết ngày hôm qua:

var content  = new Queue<Pair<Regex, Func<string, bool>>>();
...
foreach (var entry in content) { ... }

Điều này sẽ cực kỳ dài dòng mà không có var.

Phụ lục: Một ít thời gian dành cho một ngôn ngữ có suy luận kiểu thực (ví dụ F #) sẽ cho thấy trình biên dịch tốt như thế nào để có được loại biểu thức đúng. Nó chắc chắn có nghĩa là tôi có xu hướng sử dụng varnhiều nhất có thể, và sử dụng một loại rõ ràng bây giờ chỉ ra rằng biến không phải là loại của biểu thức khởi tạo.


Yup, trình biên dịch thông minh hơn chúng ta, vượt qua nó!
Stewol

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.