我正在围绕 TryParse 开发通用包装器,如下所示:
public delegate bool ParseDelegate<T>(string s, out T result);
public static T? ParseOrNull<T>(this string value, ParseDelegate<T> parse) where T : struct
{
T result;
var parsed = parse(value, out result);
return parsed ? result : (T?)null;
}
[Test]
public void ParsesValidInt()
{
Assert.AreEqual(1234, "1234".ParseOrNull<int>(int.TryParse));
}
[Test]
public void ParsesValidDecimal()
{
Assert.AreEqual(12.34M, "12.34".ParseOrNull<decimal>(decimal.TryParse));
}
这有点重复。有没有办法完全避免提及 int.TryParse,以便我的调用如下所示:
"1234".ParseOrNull<int>()
最佳答案
Is there a way to avoid mentioning int.TryParse at all, so that my calls look as follows:
不是直接的,因为 TryParse
不是共享接口(interface)的一部分。如果这些值类型有一个共享接口(interface),这将可以通过约束实现。
就我个人而言,我不建议为此使用扩展方法。我宁愿把它写成更像这样的东西:
public static class Parse
{
public delegate bool ParseDelegate<T>(string s, out T result);
public static T? FromString<T>(string value, ParseDelegate<T> parse) where T : struct
{
T result;
var parsed = parse(value, out result);
return parsed ? result : (T?)null;
}
public static int? ToNullableInt32(string value)
{
return FromString<int>(value, int.TryParse);
}
public static double? ToNullableDouble(string value)
{
return FromString<double>(value, double.TryParse);
}
}
这会预先增加一些开销,但可以让您非常干净地编写这些内容,即:
int? first = Parse.FromString<int>("1234", int.TryParse);
int? second = Parse.ToNullableInt32("1234");
double? third = Parse.ToNullableDouble("1234");
我认为放置扩展方法没有什么值(value),尤其是在像 string
(无处不在)这样的东西上,因为它“污染”了 string 本身的编译。你会在任何你使用字符串的地方看到这个 - 基本上,任何时候你使用这个命名空间,你最终都会在你的智能感知中使用这些解析方法等等。此外,这看起来更像是一个“实用程序”而不是应该出现的东西作为字符串本身的内置功能,这就是为什么我个人更喜欢为它创建一个单独的类。
关于c# - 如何编写通用扩展方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9099609/