次のコードについて質問があります。
class CurrentDate
{
static void Main()
{
Console.WriteLine(DateTime.Now);
}
}
ドキュメントによると:
指定されたフォーマット情報を使用して、指定されたオブジェクトの配列のテキスト表現と、それに続く現在の行末記号を標準出力ストリームに書き込みます。
だから私の質問は:どうしてWriteLine
はDateTime
オブジェクトのテキスト表現を知っているのですか?つまり、自分のクラスから自分のオブジェクトを作成した場合、値をテキストに変換する方法をどのように知ることができるでしょうか。さらに、値が何であるかをどのように知るのでしょうか?オブジェクトの「値」をどのように定義できますか?
WriteLineがDateTimeオブジェクトのテキスト表現を認識するのはなぜですか?つまり、自分のクラスから自分のオブジェクトを作成した場合、値をテキストに変換する方法をどのように知ることができるでしょうか。
_Console.WriteLine
_には オーバーロードのセット 特定のタイプ(主にプリミティブ)に一致します。コンパイラーがオーバーロードを指定されたタイプと一致させない場合、_System.Object
_(単一のパラメーターを指定することを許可)をとるオーバーロードと一致します。その場合、型がIFormattable
を実装しているかどうかを確認し、実装している場合は IFormattable.ToString(null, Formatter)
を呼び出します。そうでない場合は、オブジェクトでToString
を呼び出します。 ToString
は、すべてのオブジェクトが継承する_System.Object
_で定義されています。カスタム表現が必要なすべてのオブジェクトは、DateTime
のように、デフォルトの動作をオーバーライドします。
たとえば、Foo
文字列プロパティを持つBar
クラスがあり、Foo
を渡すときに意味のあるものを_Console.WriteLine
_に出力させたいとします。
_public class Foo
{
public string Bar { get; set; }
public override string ToString()
{
return Bar;
}
}
_
そして今、私たちはそれを渡したいと思います_Console.WriteLine
_:
_public static void Main(string[] args)
{
var foo = new Foo { Bar = "bar" };
Console.WriteLine(foo);
}
_
「バー」を生成します。
あなたの場合のように、Console.WriteLine(DateTime)
にはオーバーロードがないので、Console.WriteLine(Object)
オーバーロードが呼び出され、 このオーバーロードはTextWriter.WriteLine(object)
overload これは として実装 :
_IFormattable f = value as IFormattable;
if (f != null)
WriteLine(f.ToString(null, FormatProvider));
else
WriteLine(value.ToString());
_
ご覧のとおり、このメソッドは、このオブジェクトタイプが IFormattable
interface を実装しているかどうかをチェックします。 Datetime
はこのインターフェースを実装します なので、f.ToString(null, FormatProvider)
が呼び出されます。このメソッドの ドキュメント から最初のパラメータは次のとおりです。
IFormattable実装のタイプに対して定義されたデフォルトの形式を使用するためのnull参照(Visual BasicではNothing)。
そして DateTime.ToString(String, IFormatProvider)
メソッドのドキュメントから:
Formatがnullまたは空の文字列( "")の場合、標準のフォーマット指定子 _
"G"
_ 。が使用されます。
つまり、表現は ShortDatePattern
と LongTimePattern
プロパティの組み合わせになります CurrentCulture
カスタムクラスに特別な形式が必要な場合は、タイプの .ToString()
メソッドをオーバーライド で動作を変更できます。
一部の人の考えに反して、DateTime.ToString()
は呼び出されません。 .NETでは、オブジェクトはそれ自体を「文字列化」する2つの方法があります。string Object.ToString()
メソッドをオーバーライドする方法と IFormattable
インターフェイスを実装する方法です。 DateTime
は両方を行います。
今...やってみると
_Console.WriteLine(DateTime.Now);
_
void public static void WriteLine(Object value)
オーバーロードが選択されています(VisualStudioでCtrlキーを押しながらWriteLine
をクリックすると表示されます)。このメソッドは、単に TextWriter.WriteLine(value)
メソッドを呼び出します。
_IFormattable f = value as IFormattable;
if (f != null)
WriteLine(f.ToString(null, FormatProvider));
else
WriteLine(value.ToString());
_
これらはすべて、ILSpyを使用して_Console.WriteLine
_を探すことで簡単に確認できます。