拳击从bool转换为通用界面<t> </t>

时间:2013-09-08 11:38:55

标签: c# generics casting boxing

这是我的代码的简化版本(我只需要提供线索)。

假设我有一个界面:

public interface IParse <T>
{
    bool TryParse (string value, out T result);
}

这是我的Class

的一种方法
public static T GetParsedValueOrDefault<T>(string val)  where T : IParse<T>
{
        T ret = default (T);
        ret.TryParse(val, out ret);
        return ret
}

我不能使用这种语法:

Class.GetParsedValueOrDefault<bool>("False"); //Error

我收到错误:

There is no boxing conversion from 'bool' to 'IParse<bool>'

如何使这个或任何建议的类似方法起作用?

P / S:嘿,搜索大师,请指出它与(tnx)重复的问题

3 个答案:

答案 0 :(得分:1)

好的,我已经第二次重写了我的答案,因为我意识到为什么你认为你的代码会起作用。如果您认为int类型将自动实现您的IParse<T>接口,那么您会误解泛型/接口的工作方式。 int.Parse(和decimal.Parse等)是静态的,因此无法实现接口成员。这是可以用C ++模板完成的事情,但不能用C#(或Java)泛型完成。

一种解决方案是使用委托。它并不像你想要的那样优雅,但它并不太糟糕:

public delegate bool Parser<T>(string s, out T result);

public static T GetParsedValueOrDefault<T>(string val, Parser<T> parser)
{
    T result;
    bool success = parser(val, out result);
    return success ? result : default(T);
}

// Examples
int result = GetParsedValueOrDefault<int>("123", int.TryParse);
Console.WriteLine(result); // "123"

decimal result = GetParsedValueOrDefault<decimal>("123.456", decimal.TryParse);
Console.WriteLine(result); // "123.456"

decimal result = GetParsedValueOrDefault<decimal>("invalid", decimal.TryParse);
Console.WriteLine(result); // "0.0"

答案 1 :(得分:1)

您的方法存在的问题是:从哪里获得IParse<T>的适当实施? IParse<T>是一个接口,您无法实例化接口,并且可能有多个类实现IParse<bool>

我建议您使用工厂方法:

public static class Parse
{
    public static IParse<T> Create<T>()
    {
        ...
        return ...;
    }
}

然后你的方法会这样做:

public static T GetParsedValueOrDefault<T>(string val)
{
    IParse<T> parser = Parse.Create<T>();
    T ret;
    if (parser.TryParse(val, out ret)) {
        return ret;
    }
    return default(T);
}

答案 2 :(得分:0)

也许这个

public static bool GetParsedValueOrDefault<T>(string val, out T result)  where T : IParse<T>
{
    result = default(T);
    result.TryParse(val, out result);
    return result
}

但有点奇怪。

也许你的意思是:

public static T GetParsedValueOrDefault<T>(string val)  where T : IParse<T>
{
    var result = default(T);
    result.TryParse(val, out result);
    return result
}