TryParse一般为空的类型

本文关键字:类型 TryParse | 更新日期: 2023-09-27 18:16:17

我已经为以下Nullable类型编写了重载静态TryParse方法:int?, short?, long?, double?, DateTime?, decimal?, float?, bool?, byte?char?。下面是一些实现:

protected static bool TryParse(string input, out int? value)
{
    int outValue;
    bool result = Int32.TryParse(input, out outValue);
    value = outValue;
    return result;
}
protected static bool TryParse(string input, out short? value)
{
    short outValue;
    bool result = Int16.TryParse(input, out outValue);
    value = outValue;
    return result;
}
protected static bool TryParse(string input, out long? value)
{
    long outValue;
    bool result = Int64.TryParse(input, out outValue);
    value = outValue;
    return result;
}

逻辑在每个方法中都是相同的,只是它们使用不同的类型。难道不可能使用泛型,这样我就不需要这么多多余的代码了吗?签名看起来像这样:

bool TryParse<T>(string input, out T value);

谢谢

TryParse一般为空的类型

难道不可能使用泛型,这样我就不需要这么多多余的代码了吗?

你可以用反射来做,但那会相对较慢。否则,您可以创建一个从类型到"用于该类型的方法"的映射,但这会非常难看。除此之外,它永远不会是真正的泛型——它只适用于提供正确签名的TryParse方法的类型,这在编译时是无法知道的。

顺便说一下,我个人会考虑改变签名和行为。目前,即使value的类型是可空的,即使您返回false,它也不会在方法结束时具有空值。为什么不将返回值作为解析操作的结果,在失败时返回null ?
protected static long? TryParseInt64(string input)
{
    long outValue;
    return Int64.TryParse(input, out outValue) ? (long?) outValue : null;
}

您可以使用以下通用扩展方法

public static Nullable<TSource> TryParse<TSource>(this string input) where TSource : struct
{
    try
    {
        var result = Convert.ChangeType(input, typeof(TSource));
        if (result != null)
        {
            return (TSource)result;
        }
        return null;
    }
    catch (Exception)
    {
        return null;
    }
}

下面的调用将返回可为空的解析类型。

string s = "510";
int? test = s.TryParse<int>();
//TryParse Returns 510 and stored in variable test.
string s = "TestInt";
int? test = s.TryParse<int>();
//TryParse Returns null and stored in variable test.

作为题外话,您可以重构您的代码:

public static bool TryParse(string input, out int? value)
{
    return TryParse(input, Int32.TryParse, out value);
}
protected static bool TryParse(string input, out short? value)
{
    return TryParse(input, Int16.TryParse, out value);
}
protected static bool TryParse(string input, out long? value)
{
    return TryParse(input, Int64.TryParse, out value);
}
private static bool TryParse<T>(string input, TryParseFunc<T> tryParse, out T? value)
    where T : struct
{
    T outValue;
    bool result = tryParse(input, out outValue);
    value = outValue;
    return result;
}
private delegate bool TryParseFunc<T>(string input, out T value);