這很有趣,你應該提到它,因爲我的東西瞎搞就這樣的一天:
using System;
using System.Reflection;
static class Example
{
public static Tuple<Boolean, T?> TryParse<T>(this String candidate)
where T : struct
{
T? value = null;
Boolean success = false;
var parser = ParsingBinder<T>.GetParser();
try
{
value = parser(candidate);
success = true;
}
catch (FormatException) { }
return new Tuple<Boolean,T?>(success, value);
}
}
static class ParsingBinder<T>
{
static Func<String, T> parser;
public static Func<String, T> GetParser()
{
if (parser == null)
parser = getParser();
return parser;
}
static Func<String, T> getParser()
{
MethodInfo methodInfo
= typeof(T).GetMethod(
"Parse", new [] { typeof(String) });
if (methodInfo == null)
throw new Exception(
"Unable to retrieve a \"Parse\" method for type.");
return (Func<String, T>)Delegate
.CreateDelegate(typeof(Func<String, T>), methodInfo);
}
}
這是一個類似的做法,但認爲這是一個更好的TryParse
方法返回一個Tuple<Boolean, T?>
(這需要.NET 4)。元組的第一個屬性是一個布爾值,指示解析嘗試的成功或失敗,第二個屬性是類型爲通用類型參數的可爲空的值,如果解析失敗,則爲null
,解析成功時爲值。
它通過使用反射來檢索泛型類型參數的靜態Parse(String)
方法,並調用該方法對於在我建立它作爲一個擴展的方法來讓你做這樣的東西傳遞的字符串:
var intValue = "1234".TryParse<Int32>();
var doubleValue = "1234".TryParse<Double>();
不幸的是這不會對enums
工作,因爲他們不具備解析方法相同的簽名,所以你不能使用這個擴展來解析enum
,但它不會是很難破解這個高達爲枚舉做一個特例。
這種方法的好處之一是通過反射檢索Parse
方法的成本只會在第一次使用時產生,因爲爲所有後續使用創建靜態委託。
一兩件事 - 的唯一的事情就是笨重對這種做法是沒有任何語言擴展或語法糖,這將使這個易於使用。我希望通過此代碼實現的是使用BCL中存在的標準TryParse
方法的笨重方法。
我個人認爲,這一模式比較難看:
Int32 value;
if (Int32.TryParse(someString, out value))
// do something with value
主要是因爲它需要的時間提前一個變量聲明和使用out
參數。以上我的做法是不是真的那麼好很多:
var result = someString.TryParse<Int32>();
if (result.Item1)
// do something with result.Item2
什麼是真的很酷將看到一個建有Tuple<Boolean, T?>
的工作,使我們與這種類型工作的順利開展一個C#語言的擴展,但我越感覺到,我寫這篇文章似乎並不可行。
假設這真的作品,+1:P – 2009-12-10 05:00:47
考慮的'TryParse'沒有投擲失敗的異常,存在的主要目的,你的「好辦法」已撤消其存在的目的:HTTP: //www.codinghorror.com/blog/archives/000358.html – 2009-12-10 05:25:32
@ 280z28 - 夠公平,但我拋出的例外情況不同。當你試圖解析一個沒有'TryParse(String)'方法的類型時,就會拋出這個異常,當你調用一個普通的'TryParse'方法時,這種方法從來不會發生。這個異常無疑會被開發人員在測試中發現,並且不會在運行時發生,因此它與被解析失敗掩蓋的異常不完全相同。 – 2009-12-10 05:34:52