1

我有一个处理字符串输入的函数。

    public string Foo(string text)
    {
        // do stuff with text and
        // return processed string
    }

我在很多地方都调用了这个,我将 guid 转换为这样的字符串:

string returnValue = Foo(bar.ToString());

我真正想要的是接受任何可以转换为字符串的对象类型作为输入。所以我尝试修改函数如下:

    public string Foo(IFormattable text)
    {
        var textAsString = text.ToString();
        // do stuff with textAsString 
        // and return processed string
    }

这意味着我所有的调用都更简单:

string returnValue = Foo(bar);

它适用于所有具有 .ToString 方法的对象类型;除了字符串:)

如果我尝试将字符串传递给函数,则会收到以下编译错误:

Argument type 'string' is not assignable to parameter type 'System.IFormattable'  

这看起来很奇怪,因为 String 有一个 ToString() 方法。

为什么这不起作用?

4

3 回答 3

5

简单地说,System.String没有实现IFormattable.

如果文档对您来说还不够:

object x = "a string";
Console.WriteLine(x is IFormattable); // False

鉴于ToString()已在 上声明object,为什么不只拥有:

public string Foo(object text)
{
    var textAsString = text.ToString();
    // do stuff with textAsString 
    // and return processed string
}

实际上,ToString()声明的方法IFormattable并不是您试图调用的方法——您没有传递格式字符串或格式提供程序。

此外:

这看起来很奇怪,因为 String 有一个 ToString() 方法。

接口不是鸭式的。仅仅因为一个类型具有接口所需的所有成员并不意味着它实现了该接口。

于 2013-11-12T21:01:54.570 回答
2

String没有实现IFormattable,但您的代码也没有使用它。您可以为 a 创建一个包装类,string以便在需要的场景中IFormattable使用,如下所示:

public class FormattableString : IFormattable {
    private readonly string str;
    public FormattableString(string str) {
        this.str = str;
    }
    public string ToString() {
        return str;
    }
    public string ToString(string format, IFormatProvider formatProvider) {
        // You can add special code here to format the value of your string
        // as directed by the format passed into the method.
        return str;
    }
}

现在您可以按如下方式使用此类:

string returnValue = Foo(new FormattableString(bar));
于 2013-11-12T21:06:42.380 回答
2

首先,IFormatable不实现.ToString(),它只实现.ToString(string, IFormatProvider)。掌握了这些知识,如果您仍然想使用IFormatable最简单的方法来处理这个问题,只需为您的方法使用重载。

public string Foo(IFormattable text, string format, IFormatProvider formatProvider)
{
    return Foo(text.ToString(format, formatProvider));
}

public string Foo(IFormattable text, string format)
{
    return Foo(text.ToString(format, null));
}

public string Foo(string text)
{
    // do stuff with text and
    // return processed string
}
于 2013-11-12T21:03:14.777 回答