Cho rằng đây là một trường hợp sử dụng rất tự nhiên (nếu bạn không biết những gì as
thực sự thực hiện),Tại sao 'được' triển khai thành 'dưới dạng'?
if (x is Bar) {
Bar y = x as Bar;
something();
}
là có hiệu quả tương đương (có nghĩa là, trình biên dịch tạo CIL từ mã trên sẽ tương đương) tới:
Bar y = x as Bar;
if (y != null) {
y = x as Bar; //The conversion is done twice!
something();
}
EDIT:
tôi đoán tôi đã không được thực hiện câu hỏi của tôi rõ ràng. Tôi sẽ không bao giờ viết đoạn thứ hai vì nó tất nhiên là thừa. Tôi tuyên bố rằng CIL được tạo bởi trình biên dịch khi biên dịch đoạn mã đầu tiên tương đương với đoạn mã thứ hai, là thừa. Câu hỏi: a) Điều này có đúng không? b) Nếu vậy, tại sao is
được triển khai như vậy?
Đây là bởi vì tôi tìm thấy đoạn đầu tiên rõ ràng hơn rất nhiều và đẹp hơn thực sự tốt bằng văn bản
Bar y = x as Bar;
if (y != null) {
something();
}
KẾT LUẬN:
Tối ưu hóa các trường hợp is
/as
không được trách nhiệm của trình biên dịch, nhưng của JIT.
Ngoài ra, với kiểm tra không có hướng dẫn ít hơn (và ít tốn kém hơn cả hai phương án thay thế (is
và as
và is
và cast
).
Phụ Lục:
CIL cho như với nullcheck (.NET 3.5):
L_0001: ldarg.1
L_0002: isinst string
L_0007: stloc.0
L_0008: ldloc.0
L_0009: ldnull
L_000a: ceq
L_000c: stloc.1
L_000d: ldloc.1
L_000e: brtrue.s L_0019
L_0011: ldarg.0
L_0019: ret
CIL là và dàn diễn viên (.NET 3.5):
L_0001: ldarg.1
L_0002: isinst string
L_0007: ldnull
L_0008: cgt.un
L_000a: ldc.i4.0
L_000b: ceq
L_000d: stloc.1
L_000e: ldloc.1
L_000f: brtrue.s L_0021
L_0012: ldarg.1
L_0013: castclass string
L_0018: stloc.0
L_0019: ldarg.0
L_0021: ret
CIL là và dưới dạng (.NET 3.5):
L_0001: ldarg.1
L_0002: isinst string
L_0007: ldnull
L_0008: cgt.un
L_000a: ldc.i4.0
L_000b: ceq
L_000d: stloc.1
L_000e: ldloc.1
L_000f: brtrue.s L_0021
L_0012: ldarg.1
L_0013: isinst string
L_0018: stloc.0
L_0019: ldarg.0
L_0021: ret
Những điều này đã được chỉnh sửa cho sự ngắn gọn (các khai báo phương thức, các bước nhảy và các cuộc gọi tới một cái gì đó() đã được gỡ bỏ).
Tôi sẽ không gọi đó là một usecase điển hình, điển hình hơn sẽ là Bar y = x là Bar; if (y! = null) {do_stuff(); }. Nếu bạn đang sử dụng _as_ anyways, tại sao lại kiểm tra bằng _is_ trước? – dbemerlin
@dbemerlin: Bởi vì đoạn đầu tiên tự nhiên và dễ chịu hơn mắt nhiều so với giây. Đây chính là quan điểm của tôi. –
Người đầu tiên đọc cho tôi như thể nó được viết bởi một người không biết những gì 'làm', thành thật mà nói. – AakashM