2009-12-15 15 views
11

Dường như ngày càng nhiều C# code tôi đọc sử dụng var loại định danh:Có lý do kỹ thuật nào để sử dụng hay không sử dụng var trong C# khi loại đó được biết?

foreach (var itemChange in ItemChanges) 
{ 
    //... 
} 

thay vì rõ ràng nêu rõ loại:

foreach (ItemChange itemChange in ItemChanges) 
{ 
    //... 
} 

ngay cả khi loại được biết đến.

Tôi vẫn đang sử dụng sau phiên bản rõ ràng chỉ vì tôi nghĩ ai đó đọc sau sẽ nhanh chóng hiểu loại biến nào hơn nếu bạn sử dụng var.

Nhưng có bất kỳ kỹ thuật lý do nào để sử dụng cái này hay cách khác không?

+0

bản sao có thể có của [Điểm của từ khóa var là gì?] (Http://stackoverflow.com/questions/209199/whats-the-point-of-the-var-keyword) –

+0

cũng là bản sao của: http : //stackoverflow.com/questions/41479/use-of-var-keyword-in-c –

Trả lời

12

Không, chỉ có thể đọc được.

+2

Tôi thích câu trả lời này. Ngắn và ngọt. – RCIX

21

Không có lý do kỹ thuật. Nếu loại không thể suy ra tại thời gian biên dịch thì mã sẽ không biên dịch.

Bạn có quyền tuyên bố có những trường hợp tốt hơn nên sử dụng loại rõ ràng để có thể đọc được, ví dụ:

var obj = SomeMethod(); // what's the type? you'd have to inspect SomeMethod() 
SomeClass obj = SomeMethod(); // the type is obvious 

nhưng các trường hợp khác khi sử dụng var có ý nghĩa hoàn hảo, ví dụ:

var obj = new SomeClass(); // the type is obvious 
SomeClass obj = new SomeClass(); // the duplication of type is unnecessary 
+4

Nhưng (a) chỉ chứng minh rằng 'SomeMethod' bị đặt tên sai, không phải là thông tin kiểu là hữu ích, và (b) tại sao bạn lại quan tâm đến loại bê tông? Tôi thấy rất nhiều câu trả lời cho cuộc tranh luận 'var' giả định rằng thông tin kiểu cụ thể hỗ trợ khả năng đọc mà không trích dẫn bất kỳ bằng chứng nào cho thấy nó là như vậy. Người dùng ngôn ngữ năng động và chức năng có xu hướng không đồng ý mạnh mẽ với xác nhận rằng thông tin kiểu nội tuyến là một điều tốt. –

+1

Tôi hiểu bạn đến từ đâu, tuy nhiên a) bạn có thể không kiểm soát được tên của 'SomeMethod' b) Tôi không đặc biệt quan tâm, đây chỉ là vấn đề dễ đọc, một số người có thể thích biết loại biến khi họ đọc mã tiếp theo c) 'Người dùng ngôn ngữ năng động và chức năng' - đủ công bằng. Tôi cũng làm một số mã hóa IronPython và tôi có thể hiểu ngữ cảnh này. Tuy nhiên, đây là một câu hỏi C# –

2

No. Sử dụng var nơi cải thiện khả năng đọc và ngược lại.

2

var là tính năng C# 3.x +, phải không? mà không sử dụng, mã của bạn cũng tương thích hơn với các phiên bản khác.

Và có rất nhiều câu hỏi thú vị trong SO, khi bạn tìm kiếm "var C#"

+0

Nó thực sự là một tính năng C# 3, nhưng vẫn sẽ hoạt động tốt nếu bạn đang nhắm mục tiêu .Net 2.0 – philsquared

+0

Vâng, var được thực hiện trong .Net 2.0 như một trình biên dịch lừa, chúng tôi sử dụng nó đôi khi trong .Net2 của chúng tôi .0 ứng dụng. –

+0

Cảm ơn Phil Nash, Bạn đã đúng, Đã sửa. – YOU

3

Nói chung không có lý do kỹ thuật. Khả năng đọc - theo một trong hai hướng - là yếu tố thực sự duy nhất.

Tuy nhiên, một báo trước nhỏ là var sẽ suy ra loại tĩnh tĩnh của biến. Nếu bạn muốn một loại phụ hoặc siêu lớp, bạn sẽ cần phải tự đúc. Trong trường hợp của một foreach, như trong ví dụ của bạn, bạn thường có thể nhận được downcasting thực hiện cho bạn "miễn phí" chỉ bằng cách tuyên bố biến vòng lặp của bạn với loại phân lớp.

Các ví dụ điển hình được lặp lại trên một NodeList XML mà bạn biết là danh sách các XmlElement, nhưng Nodelist được gõ như một bộ sưu tập của XmlNode s. Tất nhiên bạn có thể sử dụng dàn diễn viên hoặc as để lấy lại loại bạn muốn, nhưng điều đó dường như sẽ đánh bại mục đích sử dụng suy luận kiểu :-)

Tất nhiên, trình biên dịch sẽ cho bạn biết điều này sớm khi bạn cố gắng sử dụng một thành viên của nút chỉ có sẵn cho XmlElement - vì vậy nó vẫn không phải là một sự khác biệt kỹ thuật.


Một điều đó là một chút khó chịu là nếu bạn sử dụng một công cụ như Resharper, nó rất hung hăng về gợi ý bạn sử dụng var trong mọi tình huống có thể. Điều này đặc biệt gây phiền nhiễu khi đề xuất bạn thay đổi, ví dụ: tuyên bố int thành một số var!

Tuy nhiên, trừ khi bạn tắt tính năng đó, bạn sẽ nhận được ít "nhiễu" hơn từ Resharper càng nhiều bạn sử dụng var.

3

Lý do kỹ thuật duy nhất tôi biết là bạn có thể thực hiện các phôi ẩn mà không cần var, ví dụ:

int i = 5; 
double a = i; // implicit cast with explicit types 

nhưng ở đây tôi rất thích var vì nó làm cho diễn viên rõ ràng; trong khi tôi không quan tâm nhiều đến các loại tôi quan tâm khi tôi thực hiện chuyển đổi loại thay đổi đại diện:

var a = (double)i; // explicit cast with implicit types 

Nhưng thực sự lý do chung là dễ đọc, như bạn đã nói. Câu hỏi mà bạn cần phải tự hỏi chính mình là tại sao bạn nghĩ loại bê tông chính xác lại quan trọng đối với khả năng đọc? Bạn có luôn viết các truy vấn LINQ gọi ra loại cụ thể không, ví dụ:

from ItemChange itemChange in ItemChanges 

// instead of 

from itemChange in ItemChanges 

Tương tự, bạn luôn gọi ra các đối số kiểu cho phương pháp chung thay vì sử dụng suy luận kiểu, ví dụ:

ItemChanges.Select<ItemChange, ItemChange>((ItemChange itemChange) => ...); 

// instead of 

ItemChanges.Select(itemChange => ...); 

Hoặc bạn có vui lòng cho phép trình biên dịch thực hiện một số công việc cho bạn và để cho nó hoạt động ra loại, với 'chi phí' không có thông tin loại rõ ràng không?

Nếu bạn hài lòng với suy luận kiểu trong LINQ và phương pháp chung, thì bạn đã đưa ra quyết định rằng bạn không có loại được viết rõ ràng ở mọi nơi và có thể bạn chưa tìm thấy mã của mình có thể đọc được ít hơn kết quả (trên thực tế, bạn có thể tìm thấy hoàn toàn ngược lại). Vì vậy, việc sử dụng var chỉ là một bước khác trong cùng một đường dẫn mà bạn đã truy cập.

+0

Việc đúc rõ ràng có thể quan trọng trong một số trường hợp nhất định, ví dụ: nếu Bộ đếm số của Bộ sưu tập trả về "đối tượng" thay vì loại chính xác. Tôi nghĩ SPListItemCollection là một ví dụ, nhưng tôi nghĩ điều này áp dụng cho tất cả các bộ sưu tập phi chung. –

+0

@Michael - đã đồng ý. Tôi nên có được rõ ràng hơn về sự khác biệt giữa đại diện thay đổi và đại diện bảo quản phôi (những người tôi thích đánh vần ra một cách rõ ràng với một nhà điều hành diễn viên là những đại diện thay đổi những người thân). Có, tôi nghĩ rằng việc sử dụng tên loại là rõ ràng hơn so với một dàn diễn viên cho các hình thức bảo quản dạng đại diện mặc dù. –

3

var là một tính năng C# 3.0 chỉ bắt buộc trong loại vô danh

Bởi vì mã sau

var v = new { Amount = 108, Message = "Hello" }; 

động tạo ra một loại vô danh mới, var sử dụng là bắt buộc. Ví dụ, var đặc biệt hữu ích trong LINQ, nơi kiểu thường được tạo động.

Trong mọi trường hợp khác, đó chỉ là vấn đề về hương vị cho ứng dụng cuối cùng (nó được giải quyết trong quá trình biên dịch). Nhưng đối với các trình đọc mã, tôi nghĩ 'var' ít thông tin hơn.

+1

Đôi khi tôi nghĩ rằng có lẽ đã có một cái gì đó giống như một từ khóa 'anon' cho những người thay vì' var'. –

0

Không có lý do kỹ thuật nào để sử dụng var, ngoài các loại ẩn danh, ở bất kỳ trạng thái nào của chương trình.

Tuy nhiên, việc sử dụng var cho phép chương trình thay đổi mà không cần chỉnh sửa chương trình.Với

public int SomeMethod(){} 
public List<T> SomeOtherMethod<T>(T parameter); 

sau đó

var x = SomeMethod(); 
var y = SomeOtherMethod(x); 

Sẽ làm việc (và y sẽ List<int>). Nếu bạn đã sử dụng

int x = SomeMethod(); 
List<int> y = SomeOtherMethod(x); 

sau đó nếu SomeMethod() đã được thay đổi để trở long, sau đó bạn sẽ phải thay đổi định nghĩa của y.

Tôi đã thấy loại điều này phổ biến trong suốt chương trình, yêu cầu hàng trăm thay đổi. Trường hợp cụ thể đã thay đổi mã truy cập dữ liệu để trả lại ReadOnlyCollection<T> thay vì List<T>. Có rất nhiều thay đổi mã cần thiết, rằng tôi đã thay đổi tất cả các đề cập rõ ràng của List<T> thành var và mã sẽ không bao giờ cần phải thay đổi lại.

-1

Có, chúng khác nhau. var loại bỏ kiểu dữ liệu gốc và một kiểu dữ liệu kiểm tra, vì vậy nó nguy hiểm hơn.

Type-kiểm tra

Một định nghĩa biến bình thường bao gồm một kiểu dữ liệu kiểm tra về việc chuyển nhượng ban đầu.

T a = init;  // type-checked 
a = b;   // type-checked 
a = c;   // type-checked 

này là mất tích khi bạn sử dụng var

var a = init; // NOT type-checked 
a = b;   // type-checked 
a = c;   // type-checked 

Các xét nghiệm thời gian biên dịch là keo nắm giữ các chương trình lớn với nhau. Loại bỏ chúng là ngu xuẩn.

tình cờ thay đổi

Một định nghĩa biến bình thường có một loại cố định - nó không thể được thay đổi ngẫu nhiên.

TOrig a = init(e);   // datatype fixed (as intended) 

Khi bạn loại bỏ kiểu dữ liệu ban đầu, bạn cho phép vô tình thay đổi loại biến. Bất kỳ thay đổi nào đối với biểu thức ban đầu đều có thể thay đổi kiểu dữ liệu của biến.

var a = init(e);   // datatype changes with init and e 

Theo thời gian, khi phần mềm được chỉnh sửa, kiểu dữ liệu có thể vô tình thay đổi.
Điều đó có thể đã xảy ra và bạn không thể biết được.

Ví dụ:

public double MaxValue = 1.2; 

    ... meanwhile, in another source file ... 

    var x = MaxValue - 1; 
    var y = IsFull(x); 

Cả x và kiểu dữ liệu y có thể được vô tình thay đổi bằng cách chỉnh sửa maxvalue.
Q. Điều này đã xảy ra chưa?

Tóm tắt

Sử dụng var biến datatype biến địa phương thành một phần di chuyển không được kiểm soát.
Càng có nhiều bộ phận chuyển động, máy càng có nhiều khả năng bị vỡ.

Loại dữ liệu rõ ràng ngăn ngừa lỗi.

Các vấn đề liên quan