我试图创建一个通用扩展,使用'TryParse'来检查字符串是否为给定类型:

public static bool Is<T>(this string input)
{
    T notUsed;
    return T.TryParse(input, out notUsed);
}

这将无法编译,因为它无法解析符号TryParse

据我所知,“TryParse”不是任何接口的一部分。

这有可能吗?

更新:

使用以下我想出的答案:

public static bool Is<T>(this string input)
{
    try
    {
        TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(input);
    }
    catch
    {
        return false;
    }

    return true;
}

它工作得很好,但我认为以这种方式使用异常对我来说不合适。

更新2:

修改为传递类型而不是使用泛型:

public static bool Is(this string input, Type targetType)
{
    try
    {
        TypeDescriptor.GetConverter(targetType).ConvertFromString(input);
        return true;
    }
    catch
    {
        return false;
    }
}

当前回答

以TryParse相关的方式使用TypeDescriptor类:

public static bool TryParse<T>(this string input, out T parsedValue)
{
    parsedValue = default(T);
    try
    {
        var converter = TypeDescriptor.GetConverter(typeof(T));
        parsedValue = (T)converter.ConvertFromString(input);
        return true;
    }
    catch (NotSupportedException)
    {
        return false;
    }
}

其他回答

你可以使用INumber<T>接口:

public static bool Is<T>(string input)
    where T : INumber<T>
{
    return T.TryParse(input, CultureInfo.InvariantCulture, out _);
}

这个接口是在。net 7中作为泛型数学的一部分引入的,它也允许你对泛型基本类型进行计算。

这也可以在。net 6中通过添加System.Runtime.Experimental NuGet包,然后将<EnablePreviewFeatures>true</EnablePreviewFeatures>添加到项目的任何PropertyGroup来实验使用。

我最近还需要一个通用的TryParse。这是我想到的;

public static T? TryParse<T>(string value, TryParseHandler<T> handler) where T : struct
{
    if (String.IsNullOrEmpty(value))
        return null;
    T result;
    if (handler(value, out result))
        return result;
    Trace.TraceWarning("Invalid value '{0}'", value);
    return null;
}

public delegate bool TryParseHandler<T>(string value, out T result);

那么这就是一个简单的调用问题:

var value = TryParse<int>("123", int.TryParse);
var value2 = TryParse<decimal>("123.123", decimal.TryParse);
public static class Primitive
{
    public static DateTime? TryParseExact(string text, string format, IFormatProvider formatProvider = null, DateTimeStyles? style = null)
    {
        DateTime result;
        if (DateTime.TryParseExact(text, format, formatProvider, style ?? DateTimeStyles.None, out result))
            return result;
        return null;
    }

    public static TResult? TryParse<TResult>(string text) where TResult : struct
    {
        TResult result;
        if (Delegates<TResult>.TryParse(text, out result))
            return result;
        return null;
    }

    public static bool TryParse<TResult>(string text, out TResult result) => Delegates<TResult>.TryParse(text, out result);

    public static class Delegates<TResult>
    {
        private delegate bool TryParseDelegate(string text, out TResult result);

        private static readonly TryParseDelegate _parser = (TryParseDelegate)Delegate.CreateDelegate(typeof(TryParseDelegate), typeof(TResult), "TryParse");

        public static bool TryParse(string text, out TResult result) => _parser(text, out result);
    }
}

当我想做几乎完全相同的事情时,我必须以艰难的方式实现它,考虑到反思。给定T,考虑typeof(T)并寻找TryParse或Parse方法,如果找到了就调用它。

这是一个“一般约束”的问题。因为你没有一个特定的界面,那么你就会陷入困境,除非你遵循前面的建议。

有关这方面的文档,请查看以下链接:

http://msdn.microsoft.com/en-us/library/ms379564 (VS.80) . aspx

它向您展示了如何使用这些约束,并应该为您提供更多的线索。