这很有趣,你应该提到它,因为我的东西瞎搞就这样的一天:
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