2009-02-20 32 views
7

tôi thấy rằng việc sử dụng như sau:Có lý do thuyết phục nào KHÔNG SỬ DỤNG từ khóa C# "bằng"?

TreeViewItem i = sender as TreeViewItem; 
if(i != null){ ... } 

là dễ dàng hơn để viết và hiểu hơn:

if(sender.GetType() == typeof(TreeViewItem)){ 
    TreeViewItem i = (TreeViewItem)sender; 
    ... 
} 

Có lý do thuyết phục không sử dụng cấu trúc đầu tiên?

+0

sender.GetType() == typeof (TreeViewItem) không phải là điều tương tự như 'người gửi như TreeViewItem'. Phép thử đó không thực hiện phân cấp thừa kế vào tài khoản, một cái gì đó 'như' và 'là' từ khóa. –

+0

Dupe? http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr/496167#496167 –

Trả lời

12

Tôi thích phôi đến as trong hầu hết các trường hợp vì thường nếu loại đối tượng sai, biểu thị lỗi. Lỗi phải gây ra ngoại lệ IMO - và InvalidCastException ở chính xác đường thực hiện dàn diễn viên rõ ràng hơn nhiều so với số NullReferenceException sau này trong mã.

as nên được sử dụng khi hợp lệ và hợp pháp để được chuyển một tham chiếu đến đối tượng thuộc loại mà bạn không muốn. Tình huống đó xảy ra, nhưng không thường xuyên như việc đúc bình thường trong kinh nghiệm của tôi.

So sánh các loại sử dụng GetType(), tuy nhiên, rất hiếm khi giải pháp phù hợp - chỉ phù hợp khi bạn muốn kiểm tra loại chính xác liên quan chứ không phải loại tương thích.

Tôi đã viết một số significantly longer answer về cuộc thảo luận "bỏ vs dưới dạng" ở nơi khác.

7

Không hề - nó mang lại cho bạn cơ hội để xác minh rằng chuyển đổi (truyền) đã được thực hiện OK. Nếu bạn làm

TreeViewItem i = (TreeViewItem) sender; 

bạn có thể bị ngoại lệ nếu diễn viên thất bại.

4

"như": nội dung hay. sử dụng nó mọi lúc.

nếu bạn thực sự muốn có một sự thay thế cho tự so sánh các loại thử:

if(person is Employee) { } 

đọc tốt hơn được nêu ra.

1

"là" nhanh hơn, nhưng điều cần ghi nhớ là:

  • "là" trả về một null thay vì ném một ngoại lệ nếu đó là một vấn đề

  • nó sẽ không làm chuyển đổi tùy chỉnh iirc

  • nó không làm việc cho reference-> giá trị

Chỉnh sửa: "là" chắc chắn là nhanh hơn (http://www.codeproject.com/KB/cs/csharpcasts.aspx)

Edit2: như vậy cơ bản là một tốc độ vs quyết định an toàn

1

Không, tôi sử dụng nó khá một chút. Nó cho phép bạn tránh InvalidCastException s một cách rõ ràng.

Ví dụ:

TreeViewItem tvItem = sender as TreeViewItem; 

if (tvItem != null) return; 

// Do stuff 

như trái ngược với:

try 
{ 
    TreeViewItem tvItem = (TreeViewItem)sender; 
    // Do stuff. 
} 
catch (InvalidCastException ex) 
{ 
    // Didn't work, do something about it 
    return; // ... or not... 
} 
+0

Bạn có thể nghĩ ra bất kỳ lý do nào mà "người gửi" sẽ không phải là một TreeViewItem khác hơn là một lỗi, trong hầu hết các trường hợp? Lỗi * nên * tăng ngoại lệ IMO. –

4

dụ của bạn sẽ được viết tốt hơn như:

if (sender is TreeViewItem) { 
    TreeViewItem i = (TreeViewItem)sender; 
    ... 
} 

Nó được chính xác loại kép này kiểm tra rằng as nhà điều hành có thể giúp tránh. Vì vậy, cho ví dụ được trích dẫn của bạn, tôi sẽ nói nó chắc chắn là một giải pháp tốt.

Tuy nhiên, có những tình huống mà bạn thực sự làm muốn có một diễn viên. Nếu bạn đang mong đợi một số TreeViewItem và không muốn gì khác, việc truyền sẽ đảm bảo rằng InvalidCastException bị ném nếu bạn được cung cấp bất kỳ thứ gì khác.

Giống như trong hầu hết các trường hợp, không có quy tắc chăn ở đây: sử dụng đúng công cụ cho đúng công việc.

+0

Lựa chọn thay thế cho ví dụ của tôi tốt hơn, cảm ơn !! – Pwninstein

+0

Biểu mẫu này cũng có thể gây ra sự cố khi đa luồng vì đối tượng có thể thay đổi loại giữa kiểm tra truyền và phép đúc thông thường. –

2

Nếu bạn muốn có một đồng bằng (không nullable) kiểu giá trị, rõ ràng điều này sẽ không làm việc, ví dụ:

int test = sender as int; 

là không hợp lệ, tuy nhiên:

int? test = sender as int?; 

được cho phép.

6

Nói chung, hai đoạn mã này là không tương đương. TreeViewItem i = sender as TreeViewItem sẽ mang lại một kết quả chính xác ngay cả khi sender là một-grand-con lớn của TreeViewItem, trong khi sender.GetType() == typeof(TreeViewItem) sẽ truechỉ khi sender là chính xác TreeViewItem và không ai trong lớp con có thể của nó.

1

Nếu nhận sai loại sẽ là lỗi, thì bạn nên sử dụng dàn diễn viên. Lý do cho điều này là có thực sự là một vấn đề và bạn nên biết về nó.

Nếu có thể giá trị sẽ là rỗng và đó không phải là lỗi trong hệ thống khi điều này xảy ra thì hãy sử dụng "dưới dạng". Lý do là bạn nên sử dụng "như" bất kỳ thời gian nào nhận được một null trở lại là chấp nhận được.

Hãy nhớ rằng bạn không thể sử dụng "dưới dạng" để chuyển đổi thành loại giá trị, vì giá trị null không được chấp nhận cho chúng. Nếu bạn có một loại giá trị và muốn sử dụng "as", bạn sẽ cần phải sử dụng một loại giá trị nullable.

When to Use "as" Versus Casting

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