泛型和可空类型 [英] Generics and nullable type

查看:138
本文介绍了泛型和可空类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有接受一个int为一个字符串,返回整数,如果解析成功或空值,否则的方法。

Say I have a method that takes an int as a string and returns the int if the parse succeeds or a null value otherwise.

    int? ParseValue(string intAsString)
    {
        int i;
        if (int.TryParse(intAsString, out i))
            return i;
        return null;
    }



如何这种方法被重新编写,以便它不仅适用与诠释?,而且还长?十进制?和日期时间? ?

How can this method be re-written so that it works not only with int?, but also long?, decimal? and DateTime? ?

推荐答案

这很有趣,你必须提到这是因为我的东西瞎搞就这样的一天:

It's funny you should mention it because I was messing around with something just like this the other day:

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 方法返回一个元组LT;布尔,T> (这需要.NET 4)。元组的第一个属性是指示解析尝试,第二个属性的成功或失败的布尔值类型的泛型类型参数,这将是一个空值如果解析失败,和值,如果解析成功。

It is a similar approach but think of it like a better TryParse method that returns a Tuple<Boolean, T?> (this requires .NET 4). The first property of the tuple is a boolean value indicating the success or failure of the parsing attempt and the second property is a nullable value typed to the generic type argument that will be null if parsing fails and the value if parsing succeeds.

它的工作原理是利用反射来获取静态解析(字符串)从泛型类型参数方法,并调用了对于在我建立它作为一个扩展的方法来让你做这样的东西传递的字符串的方法:

It works by using reflection to retrieve a static Parse(String) method from the generic type argument and invokes that method for the string that is passed in. I built it as an extension method to allow you to do stuff like this:

var intValue = "1234".TryParse<Int32>();
var doubleValue = "1234".TryParse<Double>();



不幸的是这不会对枚举工作因为他们不具备解析方法相同的签名,所以你不能使用这个扩展来解析枚举,但它不会是很难破解这个高达作出枚举的一个特例。

Unfortunately this won't work on enums since they don't have the same signature for the parse method so you couldn't use this extension to parse an enum but it wouldn't be hard to hack this up to make a special case for enums.

一个关于这种方法的好处之一是,检索的成本解析通过反射方法只发生在第一次使用,因为是所有后续的使用创造了一个静态的代表。

One of the nice things about this approach is that the cost of retrieving the Parse method via reflection is only incurred on the first use since a static delegate is created for all subsequent uses.


一件事 - 那就是笨​​重对这种做法的唯一的事情是,没有任何语言扩展或语法糖,这将使这个易于使用。我希望能达到这个代码是的存在于BCL使用标准的TryParse 方法笨拙的方式。

One more thing - the only thing that is clunky about this approach is that there is no language extensions or syntactic sugar that would make this easy to work with. What I was hoping to achieve with this code was a less clunky way of using the standard TryParse methods that exist in the BCL.

我个人认为这种模式比较难看:

I personally find this pattern rather ugly:

Int32 value;
if (Int32.TryParse(someString, out value))
    // do something with value

主要是因为它需要的时间提前一个变量声明和使用参数。上面我的做法是不是真的那么好很多:

mainly because it requires a variable declaration ahead of time and the use of an out parameter. My approach above isn't really that much better:

var result = someString.TryParse<Int32>();
if (result.Item1)
    // do something with result.Item2

什么是真的很酷将看到一个建有元组LT工作了一个C#语言的扩展;布尔,T> ,使我们与这方面的工作流畅类型,但我感觉我写这一点,它并没有真正似乎是可行的了。

What would be really cool would be to see a C# language extension that was built to work with a Tuple<Boolean, T?> that would allow us to work with this type smoothly but I get the feeling the more I write about this that it doesn't really seem that feasible.

这篇关于泛型和可空类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆