Kiểm tra null trước ToString ()


76

Đây là kịch bản ...

if (entry.Properties["something"].Value != null)
  attribs.something = entry.Properties["something"].Value.ToString();

Trong khi hiệu quả và hoạt động chính xác, điều này trông xấu xí đối với tôi. Nếu tôi không kiểm tra giá trị null trước khi thực hiện ToString () thì nó sẽ ném ra một ngoại lệ nếu thuộc tính là null. Có cách nào tốt hơn để xử lý tình huống này không?

Nhiều đánh giá cao!


Vì vậy, đầu ra sẽ là gì nếu giá trị là null?
Zach Scrivena

Nó sẽ sử dụng giá trị mặc định được gán cho attribs.something
Dscoduc

@dscoduc Tôi đang tìm thông tin HTA jQuery của bạn từ năm 2009. Vẫn còn đó chứ? Blog và trang web của bạn dường như đang ngoại tuyến.
yzorg


2
Câu hỏi của tôi là từ năm 2009 và câu hỏi mà bạn đã tham khảo là từ năm 2010 ... vậy câu hỏi kia là bản sao của tôi, phải không?
Dscoduc

Câu trả lời:


128

Cập nhật 8 năm sau (wow!) Để bao gồm toán tử điều kiện rỗng của c # 6 :

var value = maybeNull?.ToString() ?? String.Empty;

Các cách tiếp cận khác:

object defaultValue = "default";
attribs.something = (entry.Properties["something"].Value ?? defaultValue).ToString()

Tôi cũng đã sử dụng cái này, nó không quá thông minh nhưng tiện lợi:

public static string ToSafeString(this object obj)
{
    return (obj ?? string.Empty).ToString();
}

1
Bạn có biết liệu "mặc định" có thể được thay thế bằng string.Empty không?
Dscoduc

+1 và Trả lời: Chỉ cần kiểm tra nó và hoạt động hoàn hảo ... Cảm ơn bạn!
Dscoduc

Lưu ý rằng nếu phương thức thực hiện cuộc gọi chạy nhiều lần và tiêu hao được sử dụng lại thì bạn có thể đang ghi đè dữ liệu hợp lệ nhận được trên 1 lần gọi với 'mặc định' trong lần gọi tiếp theo.
xcud

@xcud: Đúng. Trong trường hợp đó, anh ta nên sử dụng đoạn mã sau: attribs.something = (entry.Properties ["something"]. Value ?? (objcet) attribs.something) .ToString ();
cấu hình

42

Nếu bạn đang nhắm mục tiêu .NET Framework 3.5, giải pháp thanh lịch nhất sẽ là một phương pháp mở rộng theo ý kiến ​​của tôi.

public static class ObjectExtensions
{
    public static string NullSafeToString(this object obj)
    {
        return obj != null ? obj.ToString() : String.Empty;
    }
}

Sau đó để sử dụng:

attribs.something = entry.Properties["something"].Value.NullSafeToString();

Xinh đẹp. Tôi vừa phải đối mặt với một chuyển đổi từ 1.1 sang 4.0 và trong 1.1, null.ToString () thực sự trả về "", vì vậy tôi có một vài nghìn lần xuất hiện để kiểm tra null-an toàn ngay bây giờ. Nếu tôi làm được điều này, điều này sẽ làm cho quá trình chuyển đổi mượt mà hơn rất nhiều!
Nicolas78

Chà, điều này đã từng giúp tôi tiết kiệm rất nhiều thời gian! Cảm ơn!
Brad

39
Convert.ToString(entry.Properties["something"].Value);

40-Tình yêu - không, điều này trả về null không phải là một chuỗi rỗng nếu giá trị là null.
Chris Peacock

@ChrisPeacock không, hãy kiểm tra tài liệu: giá trị trả về của Convert.ToString (giá trị đối tượng) là "Biểu diễn chuỗi của giá trị 'value', hoặc String.Empty nếu giá trị là null". Kiểm tra nhanh một chương trình thực tế xác nhận điều này.
Rob Gilliam

3

Thêm một chuỗi rỗng vào một đối tượng là một thành ngữ phổ biến cho phép bạn thực hiện ToStringchuyển đổi null-safe , như sau:

attribs.something = ""+entry.Properties["something"].Value;

Khi entry.Properties["something"].Valuenull, điều này lặng lẽ trả về một trống string.

Chỉnh sửa: Bắt đầu với C # 6, bạn có thể sử dụng ?.toán tử để tránh nullkiểm tra theo cách đơn giản hơn:

attribs.something = entry.Properties["something"].Value?.ToString();
//                                                     ^^

điều này ngắn gọn hơn lệnh gọi Convert.ToString kỳ lạ.
thepaulpage

@thepaulpage Có một cách thậm chí còn tốt hơn trong C # 6.
Sergey Kalinichenko

2

Bạn có thể không làm:

attribs.something = entry.Properties["something"].Value as string;

Không, bạn không thể; nếu là 'null', bạn sẽ gặp lỗi tham chiếu null.
George Stocker

1
hoạt động vì nó trả về chuỗi null nếu giá trị là null và nó không ném ra ngoại lệ.
live-love

2
Điều này không hoạt động đối với các loại giá trị. 'string str = myFloat as string;' không thành công. Bạn sẽ nhận được lỗi biên dịch sau Không thể chuyển đổi loại 'phao' thành 'chuỗi' thông qua một chuyển đổi tài liệu tham khảo, chuyển đổi quyền Anh, chuyển đổi unboxing, gói chuyển đổi, hoặc loại rỗng chuyển đổi
CleanCoder

1
Nooooo, nếu kiểu không phải là chuỗi sẽ trả về null luôn !!! đây là truyền và không phải là chuyển đổi! và sẽ không hoạt động các loại giá trị biểu mẫu!
Sawan

2
attribs.something = String.Format("{0}", entry.Properties["something"].Value);

Tuy nhiên, không chắc chắn về hiệu suất ...


2

Trong C # 6.0, bạn có thể làm điều đó một cách rất thanh lịch:

attribs.something = entry.Properties["something"].Value?.ToString();

Và đây là một bài viết về toán tử điều kiện null mới .


1

Như một biến thể cho câu trả lời của RexM:

attribs.something = (entry.Properties["something"].Value ?? attribs.something).ToString()

Nhược điểm duy nhất là attribs.something sẽ được gán một giá trị (chính nó, trong ví dụ này) ngay cả khi entry.Properties ["something"]. Giá trị là null - có thể tốn kém nếu thuộc tính .something thực hiện một số xử lý khác và / hoặc dòng này thực thi rất nhiều (giống như trong một vòng lặp).


1

Để thực hiện chính xác những gì bạn đang cố gắng thực hiện, luôn có thể sử dụng phương pháp trợ giúp:

CopyIfNotNull(entry.Properties["something"].Value, out attribs.something);

void CopyIfNotNull(string src, out string dest)
{
  if(src != null)
    dest = src;
}

Bạn không phải chỉ định "out" trong đối số thứ hai của CopyIfNotNull?
Dscoduc

vâng. Tôi nhận ra điều đó sau khi tôi đăng nó.
Mike Hall

1

Có bằng cách nào đó có thể làm điều gì đó giống như câu trả lời của Dale Ragan ở trên , nhưng ghi đè ToString () thay vì tạo một phương thức NullSafeToString () mới không? Tôi muốn điều này (hoặc trả về "null") là hành vi mặc định. Trình biên dịch (Visual C # 2010 Express) không phàn nàn khi tôi thêm phương thức sau vào ObjectExtensions lớp tĩnh công khai, nhưng phương thức này không được gọi ...

public static String ToString(this Object obj)
{
    if (obj == null)
    {
        return "null";
    }
    else
    {
        return obj.GetType().Name;
    }
}

2
Chắc chắn, vì phương pháp dụ có ưu tiên cao hơn phương pháp khuyến nông
codymanix

1
attribs.something  = string.Format("{0}",entry.Properties["something"].Value)

0

Làm thế nào về việc sử dụng một phương pháp phụ trợ như thế này:

attribs.something = getString(
    entry.Properties["something"].Value, 
    attribs.something);

static String getString(
    Object obj,
    String defaultString)
{
    if (obj == null) return defaultString;
    return obj.ToString();
}

Ngoài ra, bạn có thể sử dụng ??toán tử:

attribs.something = 
    (entry.Properties["something"].Value ?? attribs.something).ToString();

(lưu ý ToString()cuộc gọi dư thừa khi giá trị là null)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.