2012-10-01 34 views
16

Kịch bảnParse chuỗi thành số loại nullable (1 hoặc 2 liner)

Phân tích một chuỗi thành một số loại nullable. Nếu phân tích cú pháp không thành công, kết quả sẽ là null; nếu không kết quả sẽ là giá trị được phân tích cú pháp.

Câu hỏi

Để thực hiện điều này, tôi đã luôn luôn sử dụng các phương pháp đơn giản nhưng lengthily gây phiền nhiễu sau:

string numericString = "..."; 

decimal? numericValue; 
decimal temp; 
if (decimal.TryParse(numericString, out temp)) 
{ 
    numericValue = temp; 
} 
else 
{ 
    numericValue = null; 
} 

tôi sử dụng các phương pháp trên vì sau đây không biên dịch:

decimal temp; 
decimal? numericValue = decimal.TryParse(numericString, out temp) ? temp : null; 

Có ai biết phiên bản đầu tiên không bit mã ngắn gọn, gọn gàng và dễ đọc như bit thứ hai? Tôi biết tôi luôn luôn có thể viết một phương pháp mở rộng mà đóng gói bit đầu tiên của mã, nhưng tôi tự hỏi nếu có bất kỳ cách nào để làm những gì tôi muốn mà không có một phương pháp mở rộng.

Trả lời

26

Một thợ đúc chư rõ ràng đơn giản làm cho nó compilable:

decimal temp; 
// typecast either 'temp' or 'null' 
decimal? numericValue = 
    decimal.TryParse(numericString, out temp) ? temp : (decimal?)null; 

Một lựa chọn khác là sử dụng các nhà điều hành default vào loại nullable mong muốn:

decimal temp; 
// replace null with default 
decimal? numericValue = 
    decimal.TryParse(numericString, out temp) ? temp : default(decimal?); 
+0

hoặc '? (thập phân?) temp: null; 'chỉ để thêm một giao diện khác. – Marc

+3

Tôi thà sử dụng 'mặc định (thập phân?)', Tôi thấy nó dễ đọc hơn là một diễn viên ... –

+0

@Thomas Tôi thích điều đó. – Dan

11

Tôi muốn làm điều gì đó như thế này:

public delegate bool TryParseDelegate<T>(string str, out T value); 

public static T? TryParseOrNull<T>(TryParseDelegate<T> parse, string str) where T : struct 
{ 
    T value; 
    return parse(str, out value) ? value : (T?)null; 
} 

decimal? numericValue = TryParseOrNull<decimal>(decimal.TryParse, numericString); 

Hoặc bạn có thể làm cho nó là một phương pháp mở rộng:

public static T? TryParseAs<T>(this string str, TryParseDelegate<T> parse) where T : struct 
{ 
    T value; 
    return parse(str, out value) ? value : (T?)null; 
} 

decimal? numericValue = numericString.TryParseAs<decimal>(decimal.TryParse); 
+2

+1 cho một phương pháp chung có thể được sử dụng cho 'DateTime',' bool', 'int',' long', 'double', v.v. – Dan

5

Chỉ factorize nó đến một phương pháp khuyến nông:

public static decimal? ParseDecimal(this string s) 
{ 
    decimal d; 
    if (decimal.TryParse(s, out d)) 
     return d; 
    return null; 
} 

Sau đó, bạn có thể sử dụng nó như thế này:

numericValue = numericString.TryParseDecimal(); 
4

Làm thế nào về:

decimal? numericValue = 
    decimal.TryParse(numericString, out temp) ? temp : null as decimal?; 

Điều này làm cho numericValue null nếu diễn viên không thành công và là Đẹp và sạch sẽ.

2

Vấn đề là temp là một số thập phân và null ... là null. Bởi vì chúng không thuộc cùng một loại, so sánh giữa hai lỗi này và bạn gặp lỗi.

Hãy thử một trong hai:

decimal? numericValue = decimal.TryParse(numericString, out temp) ? (decimal?)temp : null; 

hoặc

decimal? numericValue = decimal.TryParse(numericString, out temp) ? (decimal?)temp : (decimal?)null; 
1

Tôi nghĩ bạn nên bọc nó trong một phương pháp để có thể đọc tốt hơn:

private decimal? ParseOrDefault(string decimalAsString, decimal? defaultIfInvalidString=null) 
{ 
    decimal result; 
    if (decimal.TryParse(decimalAsString, out result)) 
     return result; 
    return defaultIfInvalidString; 
} 

[Test] 
public void ParseOrDefaultTest() 
{ 
    decimal? actual = ParseOrDefault("12", null); 
    Assert.AreEqual(12m,actual); 

    actual = ParseOrDefault("Invalid string", null); 
    Assert.AreEqual(null, actual); 
} 
Các vấn đề liên quan