2011-02-09 40 views

Trả lời

82

Better là rất chủ quan. Ví dụ: cá nhân tôi thích int.TryParse, vì tôi thường không quan tâm đến số lý do tại sao việc phân tích cú pháp thất bại, nếu không thành công. Tuy nhiên, int.Parse lon (theo documentation) ném ba trường hợp ngoại lệ khác nhau:

  • đầu vào là null
  • đầu vào không phải là trong một định dạng hợp lệ
  • đầu vào có chứa một số mà procudes một tràn

Nếu bạn quan tâm về lý do không thành công, thì int.Parse rõ ràng là lựa chọn tốt hơn.

Như mọi khi, ngữ cảnh là vua.

+1

Trong khi tôi đồng ý với lực đẩy chung rằng ngữ cảnh là vua, tôi muốn nói rằng TryParse là * hầu như luôn luôn * tốt hơn, nó nhiều hơn một sở thích cá nhân chủ quan cao. Counterexample của bạn (phân biệt các ngoại lệ khác nhau có thể được ném) là khá bất thường, và có lẽ sẽ được mã hóa tốt hơn với một khối catch cho mỗi loại ngoại lệ hơn là bắt tất cả. – Joe

+1

@Joe: vâng, nếu bạn muốn phân biệt giữa các loại ngoại lệ khác nhau, bất cứ điều gì khác hơn là khối bắt cụ thể sẽ có vẻ rất kỳ quặc. Câu trả lời của tôi nhằm thảo luận về 'Parse' so với' TryParse' thay vì các mẫu mã cụ thể trong câu hỏi. Như tôi đã đề cập ở đâu đó trong các bình luận, tôi đồng ý rằng 'TryParse' là * hầu như luôn luôn * cách tốt hơn để đi, nhưng từ khóa là" gần như ", không phải" luôn luôn ". –

+0

@Joe: Tôi đã đưa ra lý lẽ đó. Xem trao đổi nhận xét cho câu hỏi ban đầu. Quyền của Fredrik về những tuyên bố tuyệt đối không bao giờ đúng. (OMG một nghịch lý!) –

10

Đầu tiên. Thứ hai được coi là mã hóa theo ngoại lệ.

8

Cá nhân, tôi muốn:

if (int.TryParse(string, out num)) 
{ 
    ... 
} 
4

Đầu tiên! Bạn không nên mã theo ngoại lệ.

bạn có thể rút ngắn nó để

if (int.TryParse(string, out num))

3

Thứ nhất, bởi đến nay. Như George nói, thứ hai là mã hóa bởi ngoại lệ và có tác động hiệu suất lớn. Và hiệu suất phải là một mối quan tâm, luôn luôn.

2

Bắt ngoại lệ có nhiều chi phí hơn, vì vậy tôi sẽ dùng thử TryParse.

Ngoài ra, phương pháp TryParse không ném ngoại lệ nếu chuyển đổi không thành công. Nó loại bỏ sự cần thiết phải sử dụng xử lý ngoại lệ để kiểm tra một FormatException trong trường hợp s không hợp lệ và không thể phân tích cú pháp thành công.

Đó phần cuối cùng copy-dán từ here

37

Có phải đặc biệt cho chuyển đổi đôi khi không thành công hay không được mong đợi và bình thường rằng chuyển đổi đôi khi sẽ không thành công? Nếu trước đây, hãy sử dụng một ngoại lệ ngoại lệ. Nếu sau, tránh ngoại lệ. Các ngoại lệ được gọi là "ngoại lệ" vì một lý do; bạn chỉ nên sử dụng chúng để xử lý các trường hợp đặc biệt đặc biệt.

+1

Tôi thích lời giải thích này vì tôi phân tích rất nhiều dữ liệu người dùng và liệu sự cố có được mong đợi hay không (và phải làm gì khi nó xảy ra) định hình toàn bộ dự án. – JYelton

+0

Eric, tôi muốn được nghe những suy nghĩ của bạn trên http://www.boost.org/community/error_handling.html: "' 'đây có phải là một tình huống đặc biệt (hoặc bất ngờ) không?" "Hướng dẫn này có một vòng hấp dẫn cho nó, nhưng thường là một sai lầm ... Một câu hỏi thích hợp hơn để hỏi là: '' chúng ta muốn ngăn xếp thư giãn ở đây? '' " – Jon

+0

@Jon: Một số điều đến với tâm trí. Đầu tiên, bạn không thể tranh luận với tautology rằng ngoại lệ là chính xác trong những tình huống mà bạn muốn hành vi của một ngoại lệ, nhưng bạn không thể tìm hiểu bất cứ điều gì từ nó. Thứ hai, rằng "đặc biệt" và "bất ngờ" là hai điều khác nhau. Và thứ ba, ai nói rằng việc mở thư rác có liên quan gì đến nó? Đó là một chi tiết thực hiện của C#. Các ngoại lệ được ném trong các phương thức không đồng bộ sẽ không làm giảm stack; ngăn xếp đã biến mất. Họ báo hiệu một nhiệm vụ mà một sự kiện đặc biệt đã xảy ra. Đừng nhầm lẫn giữa ngữ nghĩa với việc thực hiện. –

1

Điều gì đó khác cần lưu ý là ngoại lệ được ghi nhật ký (tùy chọn) trong cửa sổ gỡ lỗi/đầu ra của Visual Studio. Ngay cả khi chi phí hoạt động của các ngoại lệ có thể không đáng kể, hãy viết một dòng văn bản cho mỗi ngoại lệ khi gỡ lỗi có thể làm chậm mọi thứ ngay lập tức.Các ngoại lệ đáng chú ý hơn có thể bị chết đuối trong tất cả các nhiễu của các hoạt động phân tích cú pháp số nguyên không thành công.

15

Nếu nó thực sự hy vọng rằng việc chuyển đổi đôi khi sẽ thất bại, tôi muốn sử dụng int.TryParse và như vậy gọn gàng trên cùng một dòng với conditional (Ternary) operator, như thế này:

int myInt = int.TryParse(myString, out myInt) ? myInt : 0; 

Trong trường hợp này zero sẽ được sử dụng như một giá trị mặc định nếu phương thức TryParse thất bại.

Cũng thực sự hữu ích cho các loại có thể vô hiệu hóa, sẽ ghi đè lên bất kỳ giá trị mặc định nào bằng null nếu chuyển đổi không thành công.

+0

Điều này hoàn toàn tương đương với: 'int myInt; int.TryParse (myString, out myInt); '. TryParse() đã đặt kết quả là 0 khi không thành công. –

+3

Đúng, nhưng với phiên bản của tôi, bạn có thể chỉ định một giá trị mặc định * thay thế *, chẳng hạn như '10'. – greg84

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