Có an toàn để viết lại đoạn mã sau:Ghi lại HasValue vào ?? Các nhà khai thác
bool b = foo.bar.HasValue ? foo.bar.Value : false;
để
bool b = foo.bar.Value ?? false;
nơi bar
là loại nullable bool?
Có an toàn để viết lại đoạn mã sau:Ghi lại HasValue vào ?? Các nhà khai thác
bool b = foo.bar.HasValue ? foo.bar.Value : false;
để
bool b = foo.bar.Value ?? false;
nơi bar
là loại nullable bool?
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);
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'
'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
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ó.
ffoo.bar ?? false
sẽ được nhiều hơn an toàn hơn để sử dụng
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ị) .
+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
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
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
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.
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.
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 Entity2
là null
. 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 Entity2
là null
, 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(...)
.
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
Câu trả lời hay. –