2009-11-24 38 views
8
myFoo = myFoo ?? new Foo(); 

thay vìSử dụng không hợp lệ của nhà điều hành kết hợp Null?

if (myFoo == null) myFoo = new Foo(); 

Tôi thích hợp trong suy nghĩ rằng dòng đầu tiên của mã sẽ luôn thực hiện một bài tập? Ngoài ra, đây có phải là một sử dụng xấu của nhà điều hành null-coalescing?

+6

Bạn tạo lập luận thuyết phục cho toán tử '?? =' :) –

+0

@PavelMinaev trong trường hợp này, không giống với toán tử '|| ='? Nó sẽ phải thay thế một cuộc gọi 'if (! Isset (myFoo)) myFoo = new Foo();' để đảm bảo toán tử riêng của nó –

+0

Nó không giống nhau, vì '||' yêu cầu một giá trị Boolean. –

Trả lời

19

Tôi đã so sánh mã CIL của mã được tạo (đảm bảo tạo Bản phát hành - với Mã Optimize được chọn trong Thuộc tính dự án, tương ứng với công tắc /optimize trên csc.exe). Đây là những gì tôi nhận được (sử dụng VS 2008 - lưu ý rằng Foo.MaybeFoo() là một phương pháp mà đôi khi trả null, đôi khi một Foo)

GetFooWithIf:

IL_0000: call  class Application3.Foo Application3.Foo::MaybeFoo() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: brtrue.s IL_000f 
    IL_0009: newobj  instance void Application3.Foo::.ctor() 
    IL_000e: stloc.0 
    IL_000f: ldloc.0 
    IL_0010: ret 

GetFooWithCoalescingOperator:

IL_0000: call  class Application3.Foo Application3.Foo::MaybeFoo() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: dup 
    IL_0008: brtrue.s IL_0010 
    IL_000a: pop 
    IL_000b: newobj  instance void Application3.Foo::.ctor() 
    IL_0010: stloc.0 
    IL_0011: ldloc.0 
    IL_0012: ret 

Như vậy, tương tự, ngoại trừ một bản sao xếp chồng lên nhau và pop. Nếu điều này có thể được thực hiện để tạo ra sự khác biệt hiệu suất có thể đo lường được, tôi sẽ mua một chiếc mũ đặc biệt cho mục đích ăn nó; do đó, đi với một trong đó bạn cảm thấy cung cấp khả năng đọc tốt hơn.

(chỉnh sửa) oh và JITter có thể đủ thông minh để loại bỏ ngay cả sự khác biệt đó!

+0

Đây có phải là 'csc.exe/optimization +' không? –

+0

Tôi nghĩ vậy, được chỉnh sửa để làm rõ. – AakashM

+0

Tôi không biết Foo lớn như thế nào. Kích thước của nó có ảnh hưởng đến thời gian để chạy dup & pop không? – Gary

4

Bạn đúng trong dòng đầu tiên sẽ luôn thực hiện bài tập. Tôi sẽ không lo lắng về điều đó trừ khi mã được thực hiện rất thường xuyên.

+0

Điều gì sẽ ngăn trình biên dịch tối ưu hóa nó đi? – Timbo

+0

@Timbo: Tôi không quá am hiểu về việc tối ưu hóa trình biên dịch có thể hoặc không thể làm, nhưng tôi giả định rằng 'myFoo' sẽ được sử dụng ở đâu đó trong mã và điều này sẽ ngăn trình biên dịch tối ưu hóa nó đi. Nếu nó không được sử dụng ở nơi khác, đó là một câu chuyện khác. –

6

Tôi không nghĩ rằng đây là việc sử dụng không hợp lý của toán tử không hợp nhất. Khi đọc mã, nó ngắn gọn và ngắn gọn nhất có thể, và mục đích của mã là hiển nhiên.

Đúng là sử dụng toán tử kết hợp rỗng như thế này, bạn sẽ luôn nhận được bài tập, nhưng tôi sẽ không lo lắng về điều đó. (Và nếu nó thực sự hóa ra là một vấn đề về hiệu suất, bạn đã biết cách khắc phục nó).

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