次の方法で共有


System.Object.ToString メソッド

この記事では、この API のリファレンス ドキュメントに補足的な解説を提供します。

Object.ToString は、.NET の一般的な書式設定メソッドです。 表示に適するように、オブジェクトを文字列形式に変換します。 (.NET での書式設定のサポートについては、「 型の書式設定」を参照してください)。 Object.ToString メソッドの既定の実装では、オブジェクトの型の完全修飾名が返されます。

Von Bedeutung

別の種類のメンバー リストのリンクに従って、このページにアクセスした可能性があります。 これは、その型が Object.ToStringをオーバーライドしないためです。 代わりに、 Object.ToString メソッドの機能を継承します。

型は、特定の型のより適切な文字列表現を提供するために、 Object.ToString メソッドを頻繁にオーバーライドします。 また、型は、書式指定文字列やカルチャに依存する書式設定をサポートするために、 Object.ToString メソッドをオーバーロードする場合もよくあります。

既定の Object.ToString() メソッド

ToString メソッドの既定の実装では、次の例に示すように、Objectの型の完全修飾名が返されます。

Object obj = new Object();
Console.WriteLine(obj.ToString());

// The example displays the following output:
//      System.Object
let obj = obj ()
printfn $"{obj.ToString()}"
// printfn $"{obj}" // Equivalent

// The example displays the following output:
//      System.Object
Module Example3
    Public Sub Main()
        Dim obj As New Object()
        Console.WriteLine(obj.ToString())
    End Sub
End Module
' The example displays the following output:
'      System.Object

Objectは .NET のすべての参照型の基底クラスであるため、この動作は、ToString メソッドをオーバーライドしない参照型によって継承されます。 この例を次に示します。 すべてのObject1 メンバーの既定の実装を受け入れる Object という名前のクラスを定義します。 その ToString メソッドは、オブジェクトの完全修飾型名を返します。

using System;
using Examples;

namespace Examples
{
   public class Object1
   {
   }
}

public class Example5
{
   public static void Main()
   {
      object obj1 = new Object1();
      Console.WriteLine(obj1.ToString());
   }
}
// The example displays the following output:
//   Examples.Object1
type Object1() = class end

let obj1 = Object1()
printfn $"{obj1.ToString()}"
// The example displays the following output:
//   Examples.Object1
Public Class Object1
End Class

Module Example4
    Public Sub Main()
        Dim obj1 As New Object1()
        Console.WriteLine(obj1.ToString())
    End Sub
End Module
' The example displays the following output:
'   Examples.Object1

Object.ToString() メソッドをオーバーライドする

型は通常、 Object.ToString メソッドをオーバーライドして、オブジェクト インスタンスを表す文字列を返します。 たとえば、 CharInt32String などの基本型は、オブジェクトが表す値の文字列形式を返す ToString 実装を提供します。 次の例では、Object2 メソッドをオーバーライドして型名とその値を返すクラス (ToString) を定義します。

using System;

public class Object2
{
   private object value;

   public Object2(object value)
   {
      this.value = value;
   }

   public override string ToString()
   {
      return base.ToString() + ": " + value.ToString();
   }
}

public class Example6
{
   public static void Main()
   {
      Object2 obj2 = new Object2('a');
      Console.WriteLine(obj2.ToString());
   }
}
// The example displays the following output:
//       Object2: a
type Object2(value: obj) =
    inherit obj ()
    override _.ToString() =
        base.ToString() + ": " + value.ToString()

let obj2 = Object2 'a'
printfn $"{obj2.ToString()}"
// The example displays the following output:
//       Object2: a
Public Class Object2
   Private value As Object
   
   Public Sub New(value As Object)
      Me.value = value
   End Sub
   
   Public Overrides Function ToString() As String
      Return MyBase.ToString + ": " + value.ToString()
   End Function
End Class

Module Example5
    Public Sub Main()
        Dim obj2 As New Object2("a"c)
        Console.WriteLine(obj2.ToString())
    End Sub
End Module
' The example displays the following output:
'       Object2: a

次の表に、.NET の型カテゴリを示し、 Object.ToString メソッドをオーバーライドするかどうかを示します。

タイプカテゴリ Object.ToString() をオーバーライドします。 行動
クラス n/a n/a
構造 はい (ValueType.ToString) Object.ToString() と同じ
列挙 はい (Enum.ToString()) メンバー名
インターフェイス いいえ n/a
委任 いいえ n/a

ToStringのオーバーライドの詳細については、「継承元へのメモ」セクションを参照してください。

ToString メソッドをオーバーロードする

パラメーターなしの Object.ToString() メソッドをオーバーライドするだけでなく、多くの型で ToString メソッドがオーバーロードされ、パラメーターを受け入れるメソッドのバージョンが提供されます。 最も一般的に、これは、変数の書式設定とカルチャに依存する書式設定のサポートを提供するために行われます。

次の例では、 ToString メソッドをオーバーロードして、 Automobile クラスのさまざまなフィールドの値を含む結果文字列を返します。 これは、4 つの書式指定文字列を定義します。G はモデル名と年を返します。D はモデル名、年、ドア数を返します。C はモデル名、年、シリンダーの数を返します。そして A は、4 つすべてのフィールド値を含む文字列を返します。

using System;

public class Automobile
{
   private int _doors;
   private string _cylinders;
   private int _year;
   private string _model;

   public Automobile(string model, int year , int doors,
                     string cylinders)
   {
      _model = model;
      _year = year;
      _doors = doors;
      _cylinders = cylinders;
   }

   public int Doors
   { get { return _doors; } }

   public string Model
   { get { return _model; } }

   public int Year
   { get { return _year; } }

   public string Cylinders
   { get { return _cylinders; } }

   public override string ToString()
   {
      return ToString("G");
   }

   public string ToString(string fmt)
   {
      if (string.IsNullOrEmpty(fmt))
         fmt = "G";

      switch (fmt.ToUpperInvariant())
      {
         case "G":
            return string.Format("{0} {1}", _year, _model);
         case "D":
            return string.Format("{0} {1}, {2} dr.",
                                 _year, _model, _doors);
         case "C":
            return string.Format("{0} {1}, {2}",
                                 _year, _model, _cylinders);
         case "A":
            return string.Format("{0} {1}, {2} dr. {3}",
                                 _year, _model, _doors, _cylinders);
         default:
            string msg = string.Format("'{0}' is an invalid format string",
                                       fmt);
            throw new ArgumentException(msg);
      }
   }
}

public class Example7
{
   public static void Main()
   {
      var auto = new Automobile("Lynx", 2016, 4, "V8");
      Console.WriteLine(auto.ToString());
      Console.WriteLine(auto.ToString("A"));
   }
}
// The example displays the following output:
//       2016 Lynx
//       2016 Lynx, 4 dr. V8
open System

type Automobile(model: string, year: int, doors: int, cylinders: string) =
    member _.Doors = doors
    member _.Model = model
    member _.Year = year
    member _.Cylinders = cylinders

    override this.ToString() =
        this.ToString "G"

    member _.ToString(fmt) =
        let fmt = 
            if String.IsNullOrEmpty fmt then "G"
            else fmt.ToUpperInvariant()

        match fmt with
        | "G" ->
            $"{year} {model}"
        | "D" ->
            $"{year} {model}, {doors} dr."
        | "C" ->
            $"{year} {model}, {cylinders}"
        | "A" ->
            $"{year} {model}, {doors} dr. {cylinders}"
        | _ ->
            raise (ArgumentException $"'{fmt}' is an invalid format string")

let auto = Automobile("Lynx", 2016, 4, "V8")
printfn $"{auto}"
printfn $"""{auto.ToString "A"}"""
// The example displays the following output:
//       2016 Lynx
//       2016 Lynx, 4 dr. V8
Public Class Automobile
   Private _doors As Integer
   Private _cylinders As String
   Private _year As Integer
   Private _model As String
   
   Public Sub New(model As String, year As Integer, doors As Integer,
                  cylinders As String)
      _model = model
      _year = year
      _doors = doors
      _cylinders = cylinders
   End Sub
   
   Public ReadOnly Property Doors As Integer
      Get
          Return _doors
      End Get
   End Property
   
   Public ReadOnly Property Model As String
      Get
         Return _model
      End Get
   End Property
   
   Public ReadOnly Property Year As Integer
      Get
         Return _year
      End Get
   End Property
   
   Public ReadOnly Property Cylinders As String
      Get
         Return _cylinders
      End Get
   End Property
   
   Public Overrides Function ToString() As String
      Return ToString("G")
   End Function
   
   Public Overloads Function ToString(fmt As String) As String
      If String.IsNullOrEmpty(fmt) Then fmt = "G"
      
      Select Case fmt.ToUpperInvariant()
         Case "G"
            Return String.Format("{0} {1}", _year, _model)
         Case "D"
            Return String.Format("{0} {1}, {2} dr.",
                                 _year, _model, _doors)
         Case "C"
            Return String.Format("{0} {1}, {2}",
                                 _year, _model, _cylinders)
         Case "A"
            Return String.Format("{0} {1}, {2} dr. {3}",
                                 _year, _model, _doors, _cylinders)
         Case Else
            Dim msg As String = String.Format("'{0}' is an invalid format string",
                                              fmt)
            Throw New ArgumentException(msg)
      End Select
   End Function
End Class

Module Example6
    Public Sub Main()
        Dim auto As New Automobile("Lynx", 2016, 4, "V8")
        Console.WriteLine(auto.ToString())
        Console.WriteLine(auto.ToString("A"))
    End Sub
End Module
' The example displays the following output:
'       2016 Lynx
'       2016 Lynx, 4 dr. V8

次の例では、オーバーロードされた Decimal.ToString(String, IFormatProvider) メソッドを呼び出して、通貨値のカルチャに依存する書式を表示します。

using System;
using System.Globalization;

public class Example8
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "en-GB", "fr-FR",
                                "hr-HR", "ja-JP" };
      Decimal value = 1603.49m;
      foreach (var cultureName in cultureNames) {
         CultureInfo culture = new CultureInfo(cultureName);
         Console.WriteLine($"{culture.Name}: {value.ToString("C2", culture)}");
      }
   }
}
// The example displays the following output:
//       en-US: $1,603.49
//       en-GB: £1,603.49
//       fr-FR: 1 603,49 €
//       hr-HR: 1.603,49 kn
//       ja-JP: ¥1,603.49
open System.Globalization

let cultureNames =
    [| "en-US"; "en-GB"; "fr-FR"; "hr-HR"; "ja-JP" |]
let value = 1603.49m
for cultureName in cultureNames do
    let culture = CultureInfo cultureName
    printfn $"""{culture.Name}: {value.ToString("C2", culture)}"""
// The example displays the following output:
//       en-US: $1,603.49
//       en-GB: £1,603.49
//       fr-FR: 1 603,49 €
//       hr-HR: 1.603,49 kn
//       ja-JP: ¥1,603.49
Imports System.Globalization

Module Example7
    Public Sub Main()
        Dim cultureNames() As String = {"en-US", "en-GB", "fr-FR",
                                       "hr-HR", "ja-JP"}
        Dim value As Decimal = 1603.49D
        For Each cultureName In cultureNames
            Dim culture As New CultureInfo(cultureName)
            Console.WriteLine("{0}: {1}", culture.Name,
                           value.ToString("C2", culture))
        Next
    End Sub
End Module
' The example displays the following output:
'       en-US: $1,603.49
'       en-GB: £1,603.49
'       fr-FR: 1 603,49 €
'       hr-HR: 1.603,49 kn
'       ja-JP: ¥1,603.49

書式指定文字列と文化に依存する書式の詳細については、書式指定の型を参照してください。 数値でサポートされる書式指定文字列については、「 標準の数値書式指定文字列 」および「 カスタム数値書式指定文字列」を参照してください。 日付と時刻の値でサポートされる書式指定文字列については、「 標準の日付と時刻の書式指定文字列」およびカスタム日時書式指定文字列」を参照してください。

Object.ToString メソッドを拡張する

型は既定の Object.ToString メソッドを継承するため、その動作が望ましくなく、変更する必要がある場合があります。 これは、配列とコレクション クラスに特に当てはまります。 配列またはコレクション クラスの ToString メソッドでメンバーの値を表示することが予想される場合はありますが、代わりに、次の例に示すように、型の完全修飾型名が表示されます。

int[] values = { 1, 2, 4, 8, 16, 32, 64, 128 };
Console.WriteLine(values.ToString());

List<int> list = new List<int>(values);
Console.WriteLine(list.ToString());

// The example displays the following output:
//       System.Int32[]
//       System.Collections.Generic.List`1[System.Int32]
let values = [| 1; 2; 4; 8; 16; 32; 64; 128 |]
printfn $"{values}"

let list = ResizeArray values
printfn $"{list}"

// The example displays the following output:
//       System.Int32[]
//       System.Collections.Generic.List`1[System.Int32]
Imports System.Collections.Generic

Module Example
   Public Sub Main()
      Dim values() As Integer = { 1, 2, 4, 8, 16, 32, 64, 128 }
      Console.WriteLine(values.ToString())
      
      Dim list As New List(Of Integer)(values)
      Console.WriteLine(list.ToString())
   End Sub
End Module
' The example displays the following output:
'    System.Int32[]
'    System.Collections.Generic.List`1[System.Int32]

結果文字列を生成するには、いくつかのオプションがあります。

  • 型が配列、コレクション オブジェクト、または IEnumerable インターフェイスまたは IEnumerable<T> インターフェイスを実装するオブジェクトの場合は、C# の foreach ステートメントまたは Visual Basic の For Each...Next コンストラクトを使用して、その要素を列挙できます。

  • クラスが sealed されていない場合 (C#) または NotInheritable (Visual Basic の場合)、カスタマイズする Object.ToString メソッドを持つ基底クラスから継承するラッパー クラスを開発できます。 少なくとも、次の操作を行う必要があります。

    1. 必要なコンストラクターを実装します。 派生クラスは、基底クラスのコンストラクターを継承しません。
    2. Object.ToStringメソッドをオーバーライドして、必要な結果文字列を返します。

    次の例では、 List<T> クラスのラッパー クラスを定義します。 Object.ToString メソッドをオーバーライドして、完全修飾型名ではなく、コレクションの各メソッドの値を表示します。

    using System;
    using System.Collections.Generic;
    
    public class CList<T> : List<T>
    {
       public CList(IEnumerable<T> collection) : base(collection)
       { }
    
       public CList() : base()
       {}
    
       public override string ToString()
       {
          string retVal = string.Empty;
          foreach (T item in this) {
             if (string.IsNullOrEmpty(retVal))
                retVal += item.ToString();
             else
                retVal += string.Format(", {0}", item);
          }
          return retVal;
       }
    }
    
    public class Example2
    {
       public static void Main()
       {
          var list2 = new CList<int>();
          list2.Add(1000);
          list2.Add(2000);
          Console.WriteLine(list2.ToString());
       }
    }
    // The example displays the following output:
    //    1000, 2000
    
    open System
    open System.Collections.Generic
    
    type CList<'T>() = 
        inherit ResizeArray<'T>()
        
        override this.ToString() =
            let mutable retVal = String.Empty
            for item in this do
                if String.IsNullOrEmpty retVal then
                    retVal <- retVal + string item
                else
                    retVal <- retVal + $", {item}"
            retVal
    
    let list2 = CList()
    list2.Add 1000
    list2.Add 2000
    printfn $"{list2}"
    // The example displays the following output:
    //    1000, 2000
    
    Imports System.Collections.Generic
    
    Public Class CList(Of T) : Inherits List(Of T)
       Public Sub New(capacity As Integer)
          MyBase.New(capacity)
       End Sub
    
       Public Sub New(collection As IEnumerable(Of T))
          MyBase.New(collection)
       End Sub
    
       Public Sub New()
          MyBase.New()
       End Sub
    
       Public Overrides Function ToString() As String
          Dim retVal As String = String.Empty
          For Each item As T In Me
             If String.IsNullOrEmpty(retval) Then
                retVal += item.ToString()
             Else
                retval += String.Format(", {0}", item)
             End If
          Next
          Return retVal
       End Function
    End Class
    
    Module Example1
        Public Sub Main()
            Dim list2 As New CList(Of Integer)
            list2.Add(1000)
            list2.Add(2000)
            Console.WriteLine(list2.ToString())
        End Sub
    End Module
    ' The example displays the following output:
    '       1000, 2000
    
  • 目的の結果文字列を返す 拡張メソッド を開発します。 この方法では、既定のObject.ToString メソッドをオーバーライドすることはできません。つまり、拡張クラス (C#) またはモジュール (Visual Basic) では、元の型のToString メソッドの代わりに呼び出される ToString という名前のパラメーターなしのメソッドを持つことはできません。 パラメーターなしの ToString 置換には、他の名前を指定する必要があります。

    次の例では、List<T> クラスを拡張する 2 つのメソッドを定義します。パラメーターなしのToString2 メソッドと、書式指定文字列を表すToString パラメーターを持つString メソッドです。

    using System;
    using System.Collections.Generic;
    
    public static class StringExtensions
    {
       public static string ToString2<T>(this List<T> l)
       {
          string retVal = string.Empty;
          foreach (T item in l)
             retVal += string.Format("{0}{1}", string.IsNullOrEmpty(retVal) ?
                                                         "" : ", ",
                                      item);
          return string.IsNullOrEmpty(retVal) ? "{}" : "{ " + retVal + " }";
       }
    
       public static string ToString<T>(this List<T> l, string fmt)
       {
          string retVal = string.Empty;
          foreach (T item in l) {
             IFormattable ifmt = item as IFormattable;
             if (ifmt != null)
                retVal += string.Format("{0}{1}",
                                        string.IsNullOrEmpty(retVal) ?
                                           "" : ", ", ifmt.ToString(fmt, null));
             else
                retVal += ToString2(l);
          }
          return string.IsNullOrEmpty(retVal) ? "{}" : "{ " + retVal + " }";
       }
    }
    
    public class Example3
    {
       public static void Main()
       {
          List<int> list = new List<int>();
          list.Add(1000);
          list.Add(2000);
          Console.WriteLine(list.ToString2());
          Console.WriteLine(list.ToString("N0"));
       }
    }
    // The example displays the following output:
    //       { 1000, 2000 }
    //       { 1,000, 2,000 }
    
    open System
    open System.Collections.Generic
    
    type List<'T> with
        member this.ToString2<'T>() = 
            let mutable retVal = String.Empty
            for item in this do
               retVal <- retVal + $"""{if String.IsNullOrEmpty retVal then "" else ", "}{item}"""
            if String.IsNullOrEmpty retVal then "{}" else "{ " + retVal + " }"
    
        member this.ToString<'T>(fmt: string) =
            let mutable retVal = String.Empty
            for item in this do
                match box item with
                | :? IFormattable as ifmt ->
                    retVal <- retVal + $"""{if String.IsNullOrEmpty retVal then "" else ", "}{ifmt.ToString(fmt, null)}"""
                | _ ->
                    retVal <- retVal + this.ToString2()
            if String.IsNullOrEmpty retVal then "{}" else "{ " + retVal + " }"
    
    let list = ResizeArray()
    list.Add 1000
    list.Add 2000
    printfn $"{list.ToString2()}"
    printfn $"""{list.ToString "N0"}"""
    // The example displays the following output:
    //       { 1000, 2000 }
    //       { 1,000, 2,000 }
    
    Imports System.Collections.Generic
    Imports System.Runtime.CompilerServices
    
    Public Module StringExtensions
       <Extension()>
       Public Function ToString2(Of T)(l As List(Of T)) As String
          Dim retVal As String = ""
          For Each item As T In l
             retVal += String.Format("{0}{1}", If(String.IsNullOrEmpty(retVal),
                                                         "", ", "),
                                      item)
          Next
          Return If(String.IsNullOrEmpty(retVal), "{}", "{ " + retVal + " }")
       End Function
    
       <Extension()>
       Public Function ToString(Of T)(l As List(Of T), fmt As String) As String
          Dim retVal As String = String.Empty
          For Each item In l
             Dim ifmt As IFormattable = TryCast(item, IFormattable)
             If ifmt IsNot Nothing Then
                retVal += String.Format("{0}{1}",
                                        If(String.IsNullOrEmpty(retval),
                                           "", ", "), ifmt.ToString(fmt, Nothing))
             Else
                retVal += ToString2(l)
             End If
          Next
          Return If(String.IsNullOrEmpty(retVal), "{}", "{ " + retVal + " }")
       End Function
    End Module
    
    Module Example2
        Public Sub Main()
            Dim list As New List(Of Integer)
            list.Add(1000)
            list.Add(2000)
            Console.WriteLine(list.ToString2())
            Console.WriteLine(list.ToString("N0"))
        End Sub
    End Module
    ' The example displays the following output:
    '       { 1000, 2000 }
    '       { 1,000, 2,000 }
    

Windows ランタイムに関する注意事項

Windows ランタイムのクラスに対して ToString メソッドを呼び出すと、 ToStringをオーバーライドしないクラスの既定の動作が提供されます。 これは、Windows ランタイムに対して .NET が提供するサポートの一部です (Windows ストア アプリと Windows ランタイムの .NET サポートを参照)。 Windows ランタイムのクラスは Objectを継承せず、常に ToStringを実装するとは限りません。 ただし、C# または Visual Basic コードでメソッドを使用すると、常に ToStringEquals(Object)、および GetHashCode メソッドが含まれるように見えます。.NET では、これらのメソッドの既定の動作が提供されます。

共通言語ランタイムでは、の既定の実装にフォールバックする前に、Windows ランタイム オブジェクトで Object.ToString を使用します。

C# または Visual Basic で記述された Windows ランタイム クラスは、 ToString メソッドをオーバーライドできます。

Windows ランタイムと IStringable インターフェイス

Windows ランタイムには、1 つのメソッド IStringable.ToString が、で提供されるのと同等の基本的な書式設定のサポートを提供する Object.ToString インターフェイスが含まれています。 あいまいさを防ぐために、マネージド型に IStringable を実装しないでください。

マネージド オブジェクトがネイティブ コードまたは JavaScript や C++/CX などの言語で記述されたコードによって呼び出されると、 IStringable を実装しているように見えます。 共通言語ランタイムは、IStringable がマネージド オブジェクトに実装されていない場合、Object.ToString からの呼び出しをに自動的にルーティングします。

Warnung

共通言語ランタイムは、Windows ストア アプリのすべてのマネージド型に IStringable を自動的に実装するため、独自の IStringable 実装を提供しないことをお勧めします。 IStringableを実装すると、Windows ランタイム、C++/CX、または JavaScript からToStringを呼び出すときに意図しない動作が発生する可能性があります。

Windows ランタイム コンポーネントでエクスポートされるパブリックマネージド型に IStringable を実装する場合は、次の制限が適用されます。

  • IStringable インターフェイスは、次のように "クラス実装" リレーションシップでのみ定義できます。

    public class NewClass : IStringable
    
    Public Class NewClass : Implements IStringable
    
  • インターフェイスに IStringable を実装することはできません。

  • パラメーターを IStringable 型として宣言することはできません。

  • IStringable は、メソッド、プロパティ、またはフィールドの戻り値の型にすることはできません。

  • 次のようなメソッド定義を使用して、基底クラスから IStringable 実装を非表示にすることはできません。

    public class NewClass : IStringable
    {
       public new string ToString()
       {
          return "New ToString in NewClass";
       }
    }
    

    代わりに、IStringable.ToString 実装は、常に基底クラスの実装をオーバーライドする必要があります。 ToString実装を非表示にするには、厳密に型指定されたクラス インスタンスで呼び出す必要があります。

さまざまな条件下で、ネイティブ コードから、IStringable を実装するマネージド型を呼び出すか、ToString 実装を非表示にするマネージド型を呼び出した場合、予期しない動作が発生する可能性があります。