And*_*are 14
你应该提一下这很有趣,因为前几天我正在搞乱这样的事情:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一种类似的方法,但将其视为一种更好的TryParse返回方法Tuple<Boolean, T?>(这需要.NET 4).元组的第一个属性是一个布尔值,表示解析尝试的成功或失败,第二个属性是类型为泛型类型参数的可空值,null如果解析失败则为值,如果解析成功,则为值.
它的工作原理是使用反射Parse(String)从泛型类型参数中检索静态方法,并为传入的字符串调用该方法.我将其构建为扩展方法,允许您执行以下操作:
var intValue = "1234".TryParse<Int32>();
var doubleValue = "1234".TryParse<Double>();
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不会起作用,enums因为它们没有相同的parse方法签名,所以你不能使用这个扩展来解析一个enum但是要为枚举做一个特殊情况并不难.
这种方法的一个好处是,Parse通过反射检索方法的成本仅在第一次使用时产生,因为为所有后续使用创建了静态委托.
还有一件事 - 这种方法唯一笨拙的是,没有语言扩展或语法糖可以使这很容易使用.我希望用这个代码实现的是使用BCL中存在的标准方法的一种不那么笨重的方式TryParse.
我个人认为这种模式相当难看:
Int32 value;
if (Int32.TryParse(someString, out value))
// do something with value
Run Code Online (Sandbox Code Playgroud)
主要是因为它需要提前声明变量并使用out参数.我上面的方法并没有那么好:
var result = someString.TryParse<Int32>();
if (result.Item1)
// do something with result.Item2
Run Code Online (Sandbox Code Playgroud)
真正酷的是看到一个C#语言扩展,它是为了Tuple<Boolean, T?>让我们能够顺利地使用这种类型而构建的,但是我觉得我写的更多,它看起来并不可行.
| 归档时间: |
|
| 查看次数: |
7265 次 |
| 最近记录: |