"No overload for method 'ToString' takes 1 arguments" 在 C# 泛型方法中

"No overload for method 'ToString' takes 1 arguments" in a C# generic method

我正在尝试编写一个 C# 泛型方法,它接受 nullable 十进制和双精度值并将它们转换为字符串表示形式。

尽管我正在访问可空参数的 .Value,但我收到错误消息“方法 'ToString' 没有重载需要 1 个参数”。

这是我的代码。我做错了什么?

public static string ToThousandSeparated<T>(T? value, string naString = "") where T : struct
{
    if (value.HasValue)
    {
        T val = value.Value;
        return val.ToString("N0");
    }

    return naString;
}

object 只定义方法 string ToString() (没有参数)。 Int32 等对象定义了自己的 string ToString(string) 方法。

但是,有一个名为 IFormattable 的有用接口,它提供了 string ToString(string, IFormatProvider) 方法。因此,您可以将自己限制在实现 IFormattable:

的所有 T
public static string ToThousandSeparated<T>(T? value, string naString = "")
    where T : struct, IFormattable
{
    if (value.HasValue)
    {
        T val = value.Value;
        return val.ToString("N0", null);
    }

    return naString;
}

或接受任何东西,但在运行时测试它是否实现了IFormattable

public static string ToThousandSeparated<T>(T? value, string naString = "")
    where T : struct
{
    if (value.HasValue)
    {
        T val = value.Value;
        return val is IFormattable formattable ? formattable.ToString("N0", null) : val.ToString();
    }

    return naString;
}

当您使用 .ToString() 时,它会在两个地方查找重载解析。

它会首先检查您调用的对象是否重载了 ToString 方法。

如果没有,它将默认调用 Object.ToString

在您的示例中,您希望使用可为 null 的 decimal,它会用接受参数的多个版本覆盖 ToString

但是,由于您是从通用方法调用它,编译器无法知道您调用 ToString() 的对象是 decimal 它所知道的是 Tstruct.

考虑使用 is operator

检查对象是否为 IFormattable