受Charlie Brown在此处发布的解决方案的启发,我使用反射创建了一个通用的TryParse函数,可选择输出已解析的值:
public static bool TryParse<T>(string value, out T result) where T : struct {
var tryParseMethod = typeof(T).GetMethod("TryParse", BindingFlags.Static | BindingFlags.Public, null, new [] { typeof(string), typeof(T).MakeByRefType() }, null);
var parameters = new object[] { value, null };
var retVal = (bool)tryParseMethod.Invoke(null, parameters);
result = (T)parameters[1];
return retVal;
}
public static bool TryParse<T>(string value) where T : struct {
T throwaway;
var retVal = TryParse(value, out throwaway);
return retVal;
}
可以这样称呼它:
string input = "123";
decimal myDecimal;
bool myIntSuccess = TryParse<int>(input);
bool myDecimalSuccess = TryParse<decimal>(input, out myDecimal);
更新:
同时感谢YotaXP提供的解决方案,我创建了一个版本,不使用扩展方法但仍具有单例,最大程度地减少了需要进行反射的需求:
public static class TryParseHelper<T> where T : struct {
private delegate bool TryParseFunc(string str, out T result);
private static TryParseFunc tryParseFuncCached;
private static TryParseFunc tryParseCached {
get {
return tryParseFuncCached ?? (tryParseFuncCached = Delegate.CreateDelegate(typeof(TryParseFunc), typeof(T), "TryParse") as TryParseFunc);
}
}
public static bool TryParse(string value, out T result) {
return tryParseCached(value, out result);
}
public static bool TryParse(string value) {
T throwaway;
return TryParse(value, out throwaway);
}
}
这样调用:
string input = "987";
decimal myDecimal;
bool myIntSuccess = TryParseHelper<int>.TryParse(input);
bool myDecimalSuccess = TryParseHelper<decimal>.TryParse(input, out myDecimal);
`protected Boolean TryParse(Object value, out T result)
{
result = default(T);
var convertor = TypeDescriptor.GetConverter(typeof(T));
if (convertor == null || !convertor.IsValid(value)) { return false; }
result = (T)convertor.ConvertFrom(value);
return true;
}`
- CastroXXLConvertFrom(value)
方法包装在try-catch
块中以捕获异常)。 - Piers Myers