【问题标题】:"No overload for method 'ToString' takes 1 arguments" in a C# generic methodC# 泛型方法中的“方法 'ToString' 没有重载需要 1 个参数”
【发布时间】:2021-05-19 13:13:38
【问题描述】:

我正在尝试编写一个 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;
}

【问题讨论】:

  • 在您的代码中,T 是一个 ValueType,它只有一个 ToString 重载,不带任何参数。 docs.microsoft.com/en-us/dotnet/api/…
  • 这里的问题是T 不一定是struct,它的ToString(string format) 定义像intdobule 那样。也许传入一个Func&lt;T, string&gt;,这样您就可以指定如何格式化该值。或者,如果您只需要 decimal?double? 使用它,则为每个编写两个单独的方法。
  • 只写两个方法。如果不添加任何方法,则使此方法通用并不能解决任何问题。

标签: c# tostring generic-method


【解决方案1】:

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

但是,有一个名为IFormattable 的有用接口,它提供了一个string ToString(string, IFormatProvider) 方法。所以你可以限制自己使用所有实现IFormattableT

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;
}

【讨论】:

  • 这里不叫'object.ToString',而是'ValueType.ToString`
  • 第二个选择(带有测试的那个)的问题是,如果不是IFormattable,那么该方法不会执行预期的操作,并且调用者无法知道调用没有将数千人分开。恕我直言,在这个用例中,第一个选项更安全。无论如何,我赞成这个答案
  • 确实,第一个应该很明显,如果你想强制人们只用IFormattable类型,第二个如果你想做到最好-努力尝试格式化参数
【解决方案2】:

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

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

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

在您的示例中,您想使用可以为空的decimal,它会覆盖ToString,并带有几个接受参数的版本。

但是,由于您是从泛型方法调用它,编译器无法知道您调用的对象 ToString()decimal,它只知道 T 是 @987654330 @。

考虑使用is operator检查对象是否为IFormattable

【讨论】:

    猜你喜欢
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多