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

まず第一に、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 に答える