我有一个处理字符串输入的函数。
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()方法。
为什么这不起作用?
答案 0 :(得分:5)
简单地说,System.String
没有实现IFormattable
。
如果文档不够:
object x = "a string";
Console.WriteLine(x is IFormattable); // False
鉴于ToString()
is declared on object
,为什么不只是:
public string Foo(object text)
{
var textAsString = text.ToString();
// do stuff with textAsString
// and return processed string
}
实际上,ToString()
method declared by IFormattable
并不是你试图调用的那个 - 你没有传递格式字符串或格式提供者。
此外:
这看起来很奇怪,因为String有一个ToString()方法。
接口不是鸭子型的。仅仅因为类型具有接口所需的所有成员并不意味着它实现了接口。
答案 1 :(得分: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
}
答案 2 :(得分:2)
String
未实现IFormattable
,但您的代码也未使用它。您可以为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));