2011-06-24 9 views

Trả lời

23

Việc sửa chữa đơn giản nhất có

bool b = foo.bar.GetValueOrDefault(); 

đó cũng là thực sự rẻ hơn so với .Value vì nó bỏ qua việc kiểm tra có giá trị. Giá trị này sẽ mặc định là default(T), thực tế là false tại đây (nó chỉ trả về giá trị của trường T cơ bản, mà không có bất kỳ séc nào).

Nếu bạn cần một mặc định khác nhau để default(T), sau đó:

var value = yourNullable.GetValueOrDefault(yourPreferredValue); 
+1

Tìm hiểu điều gì đó mới mẻ mỗi ngày. Không biết bao lâu tôi đã sử dụng 'Nullable ' và chỉ không biết về những phương pháp đó. – shambulator

+0

Câu trả lời hay. –

6

Không - đây là không an toàn.

Dòng:

bool b = foo.bar.Value ?? false; 

sẽ ném một InvalidOperationException nếu foo.bar không có giá trị.

Thay vì sử dụng

var b = foo.bar ?? false; 

Cập nhật - Tôi chỉ biết về .GetValueOrDefault(); từ câu trả lời khác - trông giống như một gợi ý rất tốt để sử dụng!


Cập nhật 2 - @ câu trả lời ProgrammingHero cũng là đúng (+1 thêm!) - dòng:

bool b = foo.bar.Value ?? false 

thực sự sẽ không biên dịch - vì Error 50 Operator '??' cannot be applied to operands of type 'bool' and 'bool'

+0

'foo.bar' thuộc loại 'bool?', Nhưng 'foo.bar.Value' chỉ là 'bool', đó là lý do bạn nên áp dụng '??' toán tử chỉ cho 'foo.bar' - có loại chính xác. Nhớ lấy '??' thay thế null bằng giá trị bạn đã chỉ định đòi hỏi một giá trị nullable hoặc một kiểu tham chiếu, và bool chỉ là một kiểu giá trị. – Matt

2

Nope.

Thuộc tính Giá trị trả về một giá trị nếu một được gán, nếu không một System.InvalidOperationException là ném.

Từ: http://msdn.microsoft.com/en-us/library/1t3y8s4s%28v=vs.80%29.aspx

Vì vậy, nếu hasValue là sai thì bạn sẽ nhận được một ngoại lệ ném vào thứ hai của bạn khi bạn cố gắng chạy nó.

2

ffoo.bar ?? false sẽ được nhiều hơn an toàn hơn để sử dụng

9

gì bạn muốn là:

bool b = foo.bar ?? false; 

Đây là (ngạc nhiên) an toàn và một mục đích sử dụng cho các nhà điều hành null-coalescing.

?? toán tử được gọi là toán tử kết hợp null và được sử dụng để xác định giá trị mặc định cho các loại giá trị giá trị có thể vô hiệu hóa cũng như các loại tham chiếu. Nó trả về toán hạng bên trái nếu nó không phải là null; nếu không nó sẽ trả về toán hạng bên phải.

Nguồn: http://msdn.microsoft.com/en-us/library/ms173224.aspx

Trong trường hợp của Nullable<T>, nó có chức năng tương đương với Nullable<T>.GetValueOrDefault(T defaultValue).

Mã:

bool b = foo.bar.Value ?? false; 

có gây ra một trình biên dịch lỗi, bởi vì bạn không thể áp dụng các nhà điều hành để loại giá trị, và Nullable<T>.Value luôn trả về một giá trị kiểu (hoặc ném một ngoại lệ khi không có giá trị) .

+0

+1 cho đốm "sẽ không biên dịch" - mặc dù tôi không đồng ý về "đáng ngạc nhiên" - chủ yếu là vì 99% thời gian tôi thấy mình sử dụng nó trên các loại giá trị :) – Stuart

+1

Thật ngạc nhiên với nhiều vì hành vi hiệu quả của null- thay đổi coalesce tùy thuộc vào việc bạn đang đối phó với tham chiếu. Đối với các kiểu tham chiếu, IL tương đương với 'x == null? x: sai; '. Đối với 'Nullable ', ?? được thay thế bằng một cuộc gọi đến 'GetValueOrDefault (T);'. Sự ngạc nhiên! –

+0

Hữu ích như câu trả lời hiện được đánh dấu là câu trả lời là, tôi cảm thấy câu trả lời này là câu trả lời thực tế cho câu hỏi của OP. – Sameer

0

foo.bar.Value đại diện cho giá trị không thể vô hiệu khi có một, và ném InvalidOperationException nếu không có giá trị thực.

2
bar.Value ?? false 

có lỗi biên dịch, bởi vì toán hạng trái của ?? toán tử phải có kiểu tham chiếu hoặc nullable.

1

Có lẽ bạn cũng có thể xem bài viết this trong Stackoverflow - đây là một kiểm tra rỗng thanh lịch theo kiểu obj.IfNotNull(lambdaExpression) - trả về đối tượng bạn muốn nếu obj không null khác null (nhưng không có ngoại lệ).

Tôi đã sử dụng nó với Khung thực thể nếu bạn đang truy cập thực thể được tham chiếu, ví dụ:

var str=Entity1.Entity2.IfNotNull(x=>x.EntityDescription) ?? string.Empty 

trả về EntityDescription chứa trong Entity2 được tham chiếu bởi Entity1 - hoặc một chuỗi rỗng nếu bất kỳ đối tượng Entity1 hoặc Entity2null. Nếu không có IfNotNull bạn sẽ nhận được một biểu hiện dài và xấu xí.

Phần mở rộng phương pháp IfNotNull được định nghĩa đó như sau:

public static TOut IfNotNull<TIn, TOut>(this TIn v, Func<TIn, TOut> f) 
    where TIn : class 
    where TOut: class 
{ 
    if (v == null) return null; else return f(v); 
} 

Cập nhật: Nếu bạn cập nhật mã để C# phiên bản 6.0 (.NET Framework 4.6 - nhưng seems to support older frameworks 4.x too), có một toán tử mới khả dụng giúp nhiệm vụ này dễ dàng: Nhà điều hành "elvis"?..

Nó hoạt động như sau:

var str=(Entity1.Entity2?.EntityDescription) ?? string.Empty 

Trong trường hợp này, nếu Entity2null, dừng đánh giá và (...) trở thành null - sau đó phần ?? string.empty thay thế null bởi string.Empty. Nói cách khác, nó hoạt động theo cách tương tự như .IfNotNull(...).