c# - 如何编写通用扩展方法?

标签 c# generics c#-4.0

我正在围绕 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/

相关文章:

c# - pull : "Expected ' ENCODING' but found 'utf-8' . 后无法加载项目”

Java泛型方法继承

jquery - 415 不支持的媒体类型从 $.ajax 调用 WCF 服务

c# - 如何使用linq删除重复记录?

javascript - 从 ASP.NET MVC 中的 AngularJS Controller 加载数据,无需加载整个页面

c# - 在c#中使用while循环,在两个num之间进行计数,仅打印可被第三个num整除的num

c# - 第三方类未在 'using' 中加载。附加类安装在哪里?

java - 接口(interface)及其子类及其类型和子类型的通用迭代器

swift - 协议(protocol)只能用作通用约束

c# - 列表<类>() 与列表<类>(0)