C# ToStringの使い方を完全解説|書式指定・オーバーライド・null対策までわかる入門ガイド
はじめに
C#で数値、日付、真偽値、オブジェクトなどを文字列に変換したいときによく使うのがToStringメソッドです。
たとえば、数値の1000を画面に表示するとき、日付を2026/05/26のような形式で出力するとき、ログにオブジェクトの状態を書き出すときなど、ToStringは非常に多くの場面で登場します。
一方で、ToString()には次のような注意点もあります。
C#object value = null;
Console.WriteLine(value.ToString()); // NullReferenceException
このように、nullに対して直接ToString()を呼び出すと例外が発生します。また、数値や日付の書式指定、カルチャによる表示形式の違い、自作クラスでのオーバーライドなど、正しく理解しておきたいポイントも多くあります。
この記事では、C#のToStringの基本的な使い方から、書式指定、カルチャ指定、オーバーライド、null対策、実務で使えるサンプルまでを入門者にもわかりやすく解説します。
1. C#のToStringとは?まず押さえる基本
1-1. ToStringの役割:値やオブジェクトを文字列に変換するメソッド
ToStringは、値やオブジェクトを文字列として表現するためのメソッドです。
たとえば、整数の123を文字列の"123"にしたい場合、次のように書けます。
C#int number = 123;
string text = number.ToString();
Console.WriteLine(text); // 123
numberはint型ですが、ToString()を呼び出すことでstring型の値に変換できます。
C#では、画面表示、ログ出力、ファイル出力、CSV作成、APIレスポンスの整形など、文字列として値を扱いたい場面が非常に多いため、ToStringは基本中の基本ともいえるメソッドです。
1-2. すべての型で使える理由:Object.ToStringとの関係
C#の多くの型でToString()が使えるのは、すべての型が基本的にSystem.Objectを基底としているためです。
Objectクラスには、次のようなToStringメソッドが定義されています。
C#public virtual string ToString();
そのため、int、double、DateTime、bool、enum、自作クラスなど、さまざまな型でToString()を呼び出せます。
ただし、型によって返される文字列は異なります。たとえば、intは数値を文字列にし、DateTimeは日付と時刻を文字列にします。一方、自作クラスで何も設定していない場合は、型名が表示されるだけです。
C#class Person
{
public string Name { get; set; }
}
Person person = new Person { Name = "Tanaka" };
Console.WriteLine(person.ToString()); // Namespace.Person のような型名が表示される
この挙動を変えたい場合は、ToStringをオーバーライドします。
1-3. ToString()の基本構文と戻り値
ToString()の基本構文は次のとおりです。
C#変数.ToString();
戻り値はstring型です。
C#int age = 30;
string result = age.ToString();
Console.WriteLine(result); // 30
また、数値や日付では書式を指定して文字列化できます。
C#int price = 1000;
Console.WriteLine(price.ToString("N0")); // 1,000
DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString("yyyy/MM/dd")); // 2026/05/26
このように、ToString()は単純な文字列変換だけでなく、見た目を整えるためにも使われます。
1-4. ToStringを使う代表的な場面
ToStringは、主に次のような場面で使われます。
数値を画面表示用の文字列にしたい場合。
C#int count = 10;
string message = count.ToString();
日付を指定形式で表示したい場合。
C#DateTime now = DateTime.Now;
string dateText = now.ToString("yyyy/MM/dd HH:mm:ss");
金額を桁区切りで表示したい場合。
C#int price = 1200000;
string priceText = price.ToString("N0"); // 1,200,000
ログ出力でオブジェクトの情報を確認したい場合。
C#Console.WriteLine(user.ToString());
文字列補間の中で内部的に文字列化したい場合。
C#int score = 95;
Console.WriteLine($"点数は{score}点です");
文字列補間では明示的にToString()を書かなくても、値が文字列として扱われます。
2. ToStringの基本的な使い方
2-1. 数値を文字列に変換する
数値型では、ToString()を使うことで数値を文字列に変換できます。
C#int number = 123;
string text = number.ToString();
Console.WriteLine(text); // 123
Console.WriteLine(text.GetType()); // System.String
intだけでなく、double、decimal、longなどでも使えます。
C#double rate = 12.345;
decimal price = 1980.5m;
long population = 125000000;
Console.WriteLine(rate.ToString()); // 12.345
Console.WriteLine(price.ToString()); // 1980.5
Console.WriteLine(population.ToString()); // 125000000
数値をそのまま文字列化するだけであればToString()で十分ですが、桁区切りや小数点の桁数を整えたい場合は書式指定を使います。
C#int amount = 1000000;
Console.WriteLine(amount.ToString("N0")); // 1,000,000
2-2. DateTimeを文字列に変換する
DateTime型もToString()で文字列に変換できます。
C#DateTime date = new DateTime(2026, 5, 26, 14, 30, 0);
Console.WriteLine(date.ToString());
ただし、DateTime.ToString()の結果は実行環境のカルチャ設定によって変わる場合があります。そのため、実務では日付形式を明示することが多いです。
C#DateTime date = new DateTime(2026, 5, 26, 14, 30, 0);
Console.WriteLine(date.ToString("yyyy/MM/dd")); // 2026/05/26
Console.WriteLine(date.ToString("yyyy-MM-dd HH:mm:ss")); // 2026-05-26 14:30:00
Console.WriteLine(date.ToString("yyyy年MM月dd日")); // 2026年05月26日
日付や時刻を扱う場合は、ToString()だけで済ませるよりも、用途に合わせて書式を指定するほうが安全です。
2-3. bool・enum・Guidを文字列に変換する
bool型のToString()は、TrueまたはFalseを返します。
C#bool isActive = true;
Console.WriteLine(isActive.ToString()); // True
小文字のtrueやfalseが必要な場合は、ToLower()などを組み合わせます。
C#bool isActive = true;
Console.WriteLine(isActive.ToString().ToLower()); // true
enumでは、列挙子名が文字列として返されます。
C#enum OrderStatus
{
Pending,
Shipped,
Completed
}
OrderStatus status = OrderStatus.Shipped;
Console.WriteLine(status.ToString()); // Shipped
GuidもToString()で文字列化できます。
C#Guid id = Guid.NewGuid();
Console.WriteLine(id.ToString());
Guidでは、ハイフンなしなどの書式指定も可能です。
C#Guid id = Guid.NewGuid();
Console.WriteLine(id.ToString("D")); // 標準形式
Console.WriteLine(id.ToString("N")); // ハイフンなし
2-4. 自作クラスでToStringを呼び出した場合の挙動
自作クラスでToString()を呼び出すと、何も設定していない場合は型名が返されます。
C#class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
Product product = new Product
{
Name = "Keyboard",
Price = 3000
};
Console.WriteLine(product.ToString());
出力例は次のようになります。
C#SampleApp.Product
これは、ProductクラスでToString()をオーバーライドしていないため、基底クラスであるObject.ToString()の動作が使われるからです。
オブジェクトの中身をわかりやすく表示したい場合は、次のようにToStringをオーバーライドします。
C#class Product
{
public string Name { get; set; }
public int Price { get; set; }
public override string ToString()
{
return $"{Name}:{Price}円";
}
}
C#Product product = new Product
{
Name = "Keyboard",
Price = 3000
};
Console.WriteLine(product.ToString()); // Keyboard:3000円
3. ToStringで書式指定する方法
3-1. ToString("format")の基本
ToStringでは、型によって書式文字列を指定できます。
C#値.ToString("書式");
数値であれば桁区切り、小数点、通貨表記などを指定できます。
C#int number = 12345;
Console.WriteLine(number.ToString("N0")); // 12,345
Console.WriteLine(number.ToString("D8")); // 00012345
日付であれば、年月日や時刻の形式を指定できます。
C#DateTime date = new DateTime(2026, 5, 26, 9, 5, 0);
Console.WriteLine(date.ToString("yyyy/MM/dd")); // 2026/05/26
Console.WriteLine(date.ToString("HH:mm:ss")); // 09:05:00
書式指定を使うことで、ユーザーに見せる文字列や帳票、ログ、CSVなどの出力を整えられます。
3-2. 数値の書式指定:桁区切り・小数点・ゼロ埋め・通貨
数値のToStringでは、標準数値書式指定文字列やカスタム数値書式指定文字列を使えます。
桁区切りを行う場合はNを使います。
C#int number = 1234567;
Console.WriteLine(number.ToString("N0")); // 1,234,567
Console.WriteLine(number.ToString("N2")); // 1,234,567.00
小数点以下の桁数を指定する場合もNやFを使えます。
C#double value = 123.4567;
Console.WriteLine(value.ToString("F2")); // 123.46
Console.WriteLine(value.ToString("N1")); // 123.5
ゼロ埋めをしたい場合はDまたはカスタム書式を使います。
C#int id = 42;
Console.WriteLine(id.ToString("D5")); // 00042
Console.WriteLine(id.ToString("00000")); // 00042
通貨形式にしたい場合はCを使います。
C#decimal price = 1980m;
Console.WriteLine(price.ToString("C")); // ¥1,980 など
通貨記号や桁区切りの形式はカルチャによって変わります。日本円として固定したい場合は、CultureInfoを指定します。
3-3. DateTimeの書式指定:yyyy/MM/dd・HH:mm:ss・曜日
DateTime.ToStringでは、日付や時刻の表示形式を細かく指定できます。
C#DateTime date = new DateTime(2026, 5, 26, 14, 30, 45);
Console.WriteLine(date.ToString("yyyy/MM/dd")); // 2026/05/26
Console.WriteLine(date.ToString("yyyy-MM-dd")); // 2026-05-26
Console.WriteLine(date.ToString("HH:mm:ss")); // 14:30:45
Console.WriteLine(date.ToString("yyyy/MM/dd HH:mm:ss")); // 2026/05/26 14:30:45
曜日を表示したい場合はdddまたはddddを使います。
C#DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString("ddd")); // 火 など
Console.WriteLine(date.ToString("dddd")); // 火曜日 など
日本語の年月日形式にしたい場合は、次のように書けます。
C#DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString("yyyy年MM月dd日")); // 2026年05月26日
月や日をゼロ埋めしたくない場合は、Mやdを使います。
C#DateTime date = new DateTime(2026, 5, 6);
Console.WriteLine(date.ToString("yyyy年M月d日")); // 2026年5月6日
3-4. enumやGuidで使える書式指定
enumでは、いくつかの書式指定が使えます。
C#enum FileAccess
{
Read = 1,
Write = 2,
Execute = 4
}
FileAccess access = FileAccess.Write;
Console.WriteLine(access.ToString("G")); // Write
Console.WriteLine(access.ToString("D")); // 2
Console.WriteLine(access.ToString("X")); // 00000002
代表的な書式は次のとおりです。
Gは通常の文字列表現を返します。
C#status.ToString("G");
Dは数値として返します。
C#status.ToString("D");
Xは16進数として返します。
C#status.ToString("X");
Guidでは、次のような書式指定が使えます。
C#Guid id = Guid.NewGuid();
Console.WriteLine(id.ToString("D")); // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Console.WriteLine(id.ToString("N")); // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Console.WriteLine(id.ToString("B")); // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
Console.WriteLine(id.ToString("P")); // (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
APIやデータベース、ログなどでGuidの形式を統一したい場合は、書式指定を明示すると安全です。
3-5. カスタム書式指定と標準書式指定の違い
ToStringの書式指定には、大きく分けて標準書式指定とカスタム書式指定があります。
標準書式指定は、N0、C、D5、F2、yyyy/MM/ddのように、あらかじめ決められた意味を持つ書式です。
C#int number = 12345;
Console.WriteLine(number.ToString("N0")); // 12,345
Console.WriteLine(number.ToString("D8")); // 00012345
カスタム書式指定は、0、#、,、.などを組み合わせて、自分で表示形式を作る方法です。
C#int number = 12345;
Console.WriteLine(number.ToString("#,0")); // 12,345
Console.WriteLine(number.ToString("000000")); // 012345
日付の場合も、yyyy、MM、dd、HH、mm、ssなどを組み合わせてカスタム形式を作れます。
C#DateTime date = new DateTime(2026, 5, 26, 9, 5, 3);
Console.WriteLine(date.ToString("yyyyMMdd")); // 20260526
Console.WriteLine(date.ToString("HH時mm分ss秒")); // 09時05分03秒
実務では、まず標準書式指定で対応できるかを考え、必要に応じてカスタム書式指定を使うとよいでしょう。
3-6. 書式指定でFormatExceptionが起きる原因
ToString("format")で不正な書式を指定すると、FormatExceptionが発生する場合があります。
たとえば、Guidに存在しない書式を指定すると例外になります。
C#Guid id = Guid.NewGuid();
Console.WriteLine(id.ToString("Invalid")); // FormatException
また、型によって使える書式は異なります。数値用の書式を日付に使ったり、日付用の書式を数値に使ったりすると、期待した結果にならないことがあります。
C#int number = 1234;
Console.WriteLine(number.ToString("yyyy/MM/dd")); // 意図した日付形式にはならない
書式指定でハマらないためには、次の点を意識しましょう。
対象の型で使える書式か確認すること。
C#price.ToString("N0"); // 数値向け
date.ToString("yyyy/MM/dd"); // DateTime向け
id.ToString("N"); // Guid向け
ユーザー入力の書式文字列をそのまま使わないこと。
C#try
{
Console.WriteLine(value.ToString(format));
}
catch (FormatException)
{
Console.WriteLine("書式が正しくありません。");
}
4. カルチャを指定したToStringの使い方
4-1. ToString(IFormatProvider)とは
ToStringには、カルチャ情報を指定できるオーバーロードがあります。
C#値.ToString(IFormatProvider provider);
値.ToString(string format, IFormatProvider provider);
IFormatProviderは、数値や日付、通貨などをどの地域の形式で表示するかを決めるための仕組みです。実際にはCultureInfoを指定することが多いです。
C#using System.Globalization;
decimal price = 1234.56m;
Console.WriteLine(price.ToString("C", new CultureInfo("ja-JP")));
Console.WriteLine(price.ToString("C", new CultureInfo("en-US")));
日本とアメリカでは通貨記号や小数点、桁区切りの表示が異なるため、同じ値でも出力結果が変わります。
4-2. CultureInfoで日本語・英語などの表示形式を変える
CultureInfoを使うと、日本語、英語、フランス語など、地域ごとの表示形式を指定できます。
C#using System.Globalization;
DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString("D", new CultureInfo("ja-JP")));
Console.WriteLine(date.ToString("D", new CultureInfo("en-US")));
Console.WriteLine(date.ToString("D", new CultureInfo("fr-FR")));
"D"は長い日付形式を表す標準書式です。カルチャを変えることで、曜日や月名の表示言語も変わります。
数値でもカルチャによって表示が変わります。
C#using System.Globalization;
double value = 1234.56;
Console.WriteLine(value.ToString("N2", new CultureInfo("ja-JP")));
Console.WriteLine(value.ToString("N2", new CultureInfo("de-DE")));
ドイツ語圏では小数点と桁区切りの表記が日本やアメリカと異なるため、表示形式も変わります。
4-3. 通貨・日付・小数点表記をカルチャごとに変える
通貨表記では、カルチャ指定が特に重要です。
C#using System.Globalization;
decimal price = 1234.56m;
Console.WriteLine(price.ToString("C", new CultureInfo("ja-JP"))); // ¥1,235 など
Console.WriteLine(price.ToString("C", new CultureInfo("en-US"))); // $1,234.56
Console.WriteLine(price.ToString("C", new CultureInfo("en-GB"))); // £1,234.56
日付も地域によって表記が変わります。
C#using System.Globalization;
DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString("d", new CultureInfo("ja-JP")));
Console.WriteLine(date.ToString("d", new CultureInfo("en-US")));
小数点や桁区切りもカルチャの影響を受けます。
C#using System.Globalization;
double value = 1234567.89;
Console.WriteLine(value.ToString("N2", new CultureInfo("ja-JP")));
Console.WriteLine(value.ToString("N2", new CultureInfo("de-DE")));
海外向けアプリケーションや、多言語対応システムでは、カルチャを意識したToStringが必要です。
4-4. InvariantCultureを使うべきケース
InvariantCultureは、特定の国や地域に依存しない固定的なカルチャです。
C#using System.Globalization;
double value = 1234.56;
string text = value.ToString(CultureInfo.InvariantCulture);
Console.WriteLine(text); // 1234.56
InvariantCultureは、主に次のような場面で使います。
設定ファイルに数値や日付を書き出す場合。
C#double value = 1234.56;
string text = value.ToString(CultureInfo.InvariantCulture);
CSVやJSONなど、機械的に処理するデータを出力する場合。
C#DateTime date = new DateTime(2026, 5, 26, 14, 30, 0);
string text = date.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);
ログやAPI連携で環境による差を避けたい場合。
C#decimal amount = 1234.56m;
string text = amount.ToString("F2", CultureInfo.InvariantCulture);
ユーザーに見せる表示ではja-JPなどのカルチャを使い、システム内部で扱う固定形式にはInvariantCultureを使う、という使い分けが実務ではよく使われます。
5. ToStringをオーバーライドする方法
5-1. 自作クラスでToStringをオーバーライドする理由
自作クラスでToString()をオーバーライドしない場合、出力されるのは基本的に型名です。
C#class User
{
public int Id { get; set; }
public string Name { get; set; }
}
User user = new User { Id = 1, Name = "Sato" };
Console.WriteLine(user.ToString()); // SampleApp.User など
これでは、ログやデバッグで中身がわかりにくくなります。
ToStringをオーバーライドすると、オブジェクトの内容をわかりやすい文字列として返せます。
C#class User
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return $"Id={Id}, Name={Name}";
}
}
C#User user = new User { Id = 1, Name = "Sato" };
Console.WriteLine(user.ToString()); // Id=1, Name=Sato
デバッグ、ログ出力、例外メッセージ、画面表示の補助などで役立ちます。
5-2. override string ToString()の基本構文
ToStringをオーバーライドする基本構文は次のとおりです。
C#public override string ToString()
{
return "返したい文字列";
}
例として、商品クラスを作ってみます。
C#class Product
{
public string Name { get; set; }
public int Price { get; set; }
public override string ToString()
{
return $"{Name}:{Price}円";
}
}
使用例は次のとおりです。
C#Product product = new Product
{
Name = "Mouse",
Price = 2500
};
Console.WriteLine(product.ToString()); // Mouse:2500円
文字列補間の中でも、自動的にToString()が使われます。
C#Console.WriteLine($"商品情報:{product}");
// 商品情報:Mouse:2500円
5-3. デバッグやログ出力で見やすい文字列を返す実装例
ログ出力向けにToStringを実装する場合は、プロパティ名と値がわかる形式にすると便利です。
C#class Order
{
public int Id { get; set; }
public string CustomerName { get; set; }
public decimal Amount { get; set; }
public DateTime OrderedAt { get; set; }
public override string ToString()
{
return $"Order(Id={Id}, CustomerName={CustomerName}, Amount={Amount:N0}, OrderedAt={OrderedAt:yyyy-MM-dd HH:mm:ss})";
}
}
使用例です。
C#Order order = new Order
{
Id = 1001,
CustomerName = "Yamada",
Amount = 25000m,
OrderedAt = new DateTime(2026, 5, 26, 10, 30, 0)
};
Console.WriteLine(order.ToString());
出力例です。
C#Order(Id=1001, CustomerName=Yamada, Amount=25,000, OrderedAt=2026-05-26 10:30:00)
ログでは、あとから見返したときに意味がわかることが重要です。そのため、単に値だけを並べるよりも、プロパティ名を含める形がおすすめです。
5-4. ToStringをオーバーライドするときの注意点
ToStringをオーバーライドするときは、いくつか注意点があります。
まず、重い処理を書かないようにしましょう。
C#public override string ToString()
{
// データベースアクセスや外部API呼び出しは避ける
return $"{Id}: {Name}";
}
ToStringはログやデバッグ、文字列補間などで気軽に呼ばれる可能性があります。重い処理や副作用のある処理を書くと、予期しないパフォーマンス低下や不具合につながります。
次に、例外をできるだけ発生させないようにしましょう。
C#public override string ToString()
{
return $"Name={Name ?? "(null)"}";
}
ToStringは安全に文字列を返すことが期待されるため、nullの可能性があるプロパティには注意が必要です。
また、機密情報を含めないことも重要です。
C#public override string ToString()
{
return $"UserName={UserName}";
// PasswordやTokenなどは出力しない
}
ログに出力される可能性があるため、パスワード、アクセストークン、個人情報などを含めないようにしましょう。
5-5. 書式指定に対応したい場合はIFormattableを使う
通常のToStringオーバーライドでは、引数なしのToString()にしか対応しません。
書式指定に対応したい場合は、IFormattableを実装します。
C#using System;
using System.Globalization;
class Product : IFormattable
{
public string Name { get; set; }
public decimal Price { get; set; }
public override string ToString()
{
return ToString("G", CultureInfo.CurrentCulture);
}
public string ToString(string format, IFormatProvider formatProvider)
{
format = string.IsNullOrEmpty(format) ? "G" : format;
return format switch
{
"G" => $"{Name}:{Price.ToString("N0", formatProvider)}円",
"N" => Name,
"P" => Price.ToString("N0", formatProvider),
_ => throw new FormatException("指定された書式はサポートされていません。")
};
}
}
使用例です。
C#Product product = new Product
{
Name = "Keyboard",
Price = 3980m
};
Console.WriteLine(product.ToString()); // Keyboard:3,980円
Console.WriteLine(product.ToString("N", null)); // Keyboard
Console.WriteLine(product.ToString("P", null)); // 3,980
このように、独自の型でも書式指定に対応できます。ただし、一般的な業務アプリでは、まずは通常のToStringオーバーライドで十分なことが多いです。
6. ToStringとnull対策
6-1. null.ToString()でNullReferenceExceptionが起きる理由
ToString()はインスタンスメソッドです。そのため、対象の変数がnullの場合、メソッドを呼び出せません。
C#object value = null;
Console.WriteLine(value.ToString()); // NullReferenceException
nullは「オブジェクトが存在しない」状態です。存在しないオブジェクトに対してToString()を呼び出そうとするため、NullReferenceExceptionが発生します。
安全に文字列化したい場合は、nullチェックを行います。
C#object value = null;
string text = value == null ? "" : value.ToString();
Console.WriteLine(text);
または、null条件演算子やnull合体演算子を使います。
C#string text = value?.ToString() ?? "";
6-2. null許容型のToStringの挙動
int?やDateTime?などのnull許容型では、値がある場合はその値のToString()結果が返され、値がない場合は空文字列が返されます。
C#int? number1 = 123;
int? number2 = null;
Console.WriteLine(number1.ToString()); // 123
Console.WriteLine(number2.ToString()); // 空文字
これは、参照型のnullに対してToString()を呼び出す場合とは異なります。
C#object value = null;
Console.WriteLine(value.ToString()); // NullReferenceException
null許容型の場合は、変数自体がNullable<T>という値型であり、そのToString()が呼び出されるため、nullでも例外になりません。
C#DateTime? date = null;
Console.WriteLine(date.ToString()); // 空文字
ただし、date.Value.ToString()のようにValueへアクセスすると、値がない場合に例外が発生します。
C#DateTime? date = null;
Console.WriteLine(date.Value.ToString()); // InvalidOperationException
6-3. Convert.ToStringとの違い
Convert.ToStringは、値を文字列に変換するためのメソッドです。
C#int number = 123;
string text = Convert.ToString(number);
Console.WriteLine(text); // 123
ToString()との大きな違いは、nullに対して比較的安全に使える点です。
C#object value = null;
string text = Convert.ToString(value);
Console.WriteLine(text); // 空文字
一方、直接ToString()を呼ぶと例外になります。
C#object value = null;
string text = value.ToString(); // NullReferenceException
ただし、コードの意図が明確な場合は?.ToString() ?? ""のように書くことも多いです。
C#object value = null;
string text = value?.ToString() ?? "";
実務では、nullを空文字として扱いたい場面ではConvert.ToStringや?.ToString() ?? ""を使うと安全です。
6-4. null条件演算子?.ToString()の使い方
null条件演算子?.を使うと、対象がnullでない場合だけToString()を呼び出せます。
C#object value = null;
string text = value?.ToString();
Console.WriteLine(text); // null
valueがnullの場合、value?.ToString()全体の結果はnullになります。例外は発生しません。
値がある場合は通常通りToString()が呼ばれます。
C#object value = 123;
string text = value?.ToString();
Console.WriteLine(text); // 123
ただし、?.ToString()だけでは結果がnullになる可能性があります。空文字にしたい場合は、null合体演算子??を組み合わせます。
C#object value = null;
string text = value?.ToString() ?? "";
Console.WriteLine(text); // 空文字
6-5. null合体演算子??でデフォルト文字列を返す方法
null合体演算子??を使うと、左辺がnullの場合に右辺の値を返せます。
C#object value = null;
string text = value?.ToString() ?? "未設定";
Console.WriteLine(text); // 未設定
値がある場合は、その値のToString()結果が使われます。
C#object value = 100;
string text = value?.ToString() ?? "未設定";
Console.WriteLine(text); // 100
画面表示で未入力を示したい場合などに便利です。
C#string name = null;
string displayName = name ?? "ゲスト";
Console.WriteLine(displayName); // ゲスト
ToStringと組み合わせる場合は、次の形がよく使われます。
C#string text = value?.ToString() ?? "";
または、デフォルト文字列を指定します。
C#string text = value?.ToString() ?? "(none)";
6-6. string.Emptyや空文字を返したい場合の書き方
nullを空文字として扱いたい場合は、次のように書けます。
C#object value = null;
string text = value?.ToString() ?? string.Empty;
string.Emptyは空文字""とほぼ同じ意味です。
C#string text1 = "";
string text2 = string.Empty;
どちらを使っても動作は同じです。チームのコーディング規約に合わせるとよいでしょう。
Convert.ToStringを使う方法もあります。
C#object value = null;
string text = Convert.ToString(value);
ただし、戻り値の扱いを明確にしたい場合は、次のように書くと意図が伝わりやすいです。
C#string text = value?.ToString() ?? string.Empty;
共通処理としてメソッド化することもできます。
C#static string ToSafeString(object value)
{
return value?.ToString() ?? string.Empty;
}
7. ToStringと他の文字列変換方法の違い
7-1. ToStringとConvert.ToStringの違い
ToString()は、対象のインスタンスに対して呼び出すメソッドです。
C#int number = 123;
string text = number.ToString();
一方、Convert.ToString()は、Convertクラスの静的メソッドです。
C#int number = 123;
string text = Convert.ToString(number);
通常の値であれば、どちらも似た結果になります。
C#int number = 123;
Console.WriteLine(number.ToString()); // 123
Console.WriteLine(Convert.ToString(number)); // 123
大きな違いはnullの扱いです。
C#object value = null;
Console.WriteLine(Convert.ToString(value)); // 空文字
Console.WriteLine(value.ToString()); // NullReferenceException
nullの可能性がある値を安全に文字列化したい場合は、Convert.ToStringまたはvalue?.ToString() ?? ""を使うとよいでしょう。
7-2. ToStringとstring.Formatの違い
string.Formatは、複数の値を文字列に埋め込んで整形するためのメソッドです。
C#int price = 1000;
string text = string.Format("価格は{0}円です", price);
Console.WriteLine(text); // 価格は1000円です
書式指定もできます。
C#int price = 1000;
string text = string.Format("価格は{0:N0}円です", price);
Console.WriteLine(text); // 価格は1,000円です
ToStringは単体の値を文字列化するために使います。
C#string text = price.ToString("N0");
string.Formatは、文章全体を組み立てるときに使います。
C#string message = string.Format("価格は{0:N0}円です", price);
現在のC#では、string.Formatよりも文字列補間を使うことが多くなっています。
C#string message = $"価格は{price:N0}円です";
7-3. ToStringと文字列補間の違い
文字列補間は、$"..."の中に変数や式を埋め込む書き方です。
C#int price = 1000;
string message = $"価格は{price}円です";
Console.WriteLine(message); // 価格は1000円です
書式指定もできます。
C#int price = 1000;
string message = $"価格は{price:N0}円です";
Console.WriteLine(message); // 価格は1,000円です
文字列補間では、内部的に値が文字列として扱われます。そのため、単純に文章を作るならToString()を明示的に書く必要はありません。
C#int age = 30;
// 冗長
string message1 = "年齢は" + age.ToString() + "歳です";
// 読みやすい
string message2 = $"年齢は{age}歳です";
単体の値を文字列化したい場合はToString、文章の中に値を埋め込みたい場合は文字列補間を使うとよいでしょう。
7-4. int.Parse・TryParseとの違い
ToStringは、値を文字列に変換するメソッドです。
C#int number = 123;
string text = number.ToString(); // int → string
一方、int.Parseやint.TryParseは、文字列を数値に変換するメソッドです。
C#string text = "123";
int number = int.Parse(text); // string → int
つまり、変換の向きが逆です。
C#int number = 123;
string text = number.ToString(); // 数値から文字列へ
string input = "456";
int result = int.Parse(input); // 文字列から数値へ
ユーザー入力など、変換に失敗する可能性がある場合はTryParseを使います。
C#string input = "abc";
if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値に変換できません。");
}
ToStringは表示用、ParseやTryParseは入力値の変換用と考えるとわかりやすいです。
7-5. どの方法を使うべきかの判断基準
値を単純に文字列化したい場合はToString()を使います。
C#string text = number.ToString();
表示形式を指定したい場合は、書式付きのToStringを使います。
C#string text = price.ToString("N0");
nullの可能性がある場合は、null対策を入れます。
C#string text = value?.ToString() ?? "";
または、Convert.ToStringを使います。
C#string text = Convert.ToString(value);
文章の中に値を埋め込みたい場合は、文字列補間がおすすめです。
C#string message = $"価格は{price:N0}円です";
文字列を数値や日付に戻したい場合は、ParseやTryParseを使います。
C#int.TryParse(input, out int number);
実務では、可読性を重視して選ぶことが大切です。単体変換はToString、文章作成は文字列補間、null対策が必要なら?.ToString() ?? ""やConvert.ToString、入力変換はTryParseという使い分けを覚えておきましょう。
8. ToStringでよくあるエラーとハマりどころ
8-1. NullReferenceExceptionが発生するケース
最もよくあるのが、nullに対してToString()を呼び出すケースです。
C#object value = null;
string text = value.ToString(); // NullReferenceException
参照型の変数はnullになる可能性があります。特に、データベースから取得した値、外部APIのレスポンス、画面入力、設定ファイルなどはnullを考慮する必要があります。
安全に書くなら、次のようにします。
C#string text = value?.ToString() ?? "";
デフォルト値を表示したい場合は、次のようにします。
C#string text = value?.ToString() ?? "未設定";
nullの可能性がある値に対して、いきなりToString()を呼ばないことが重要です。
8-2. FormatExceptionが発生するケース
書式指定が不正な場合、FormatExceptionが発生することがあります。
C#Guid id = Guid.NewGuid();
string text = id.ToString("INVALID"); // FormatException
また、独自にIFormattableを実装しているクラスで、未対応の書式を指定した場合にも発生させることがあります。
C#public string ToString(string format, IFormatProvider formatProvider)
{
return format switch
{
"G" => "通常表示",
_ => throw new FormatException("未対応の書式です。")
};
}
書式指定を使う場合は、その型でサポートされている書式か確認しましょう。
C#price.ToString("N0"); // 数値
date.ToString("yyyy/MM/dd"); // DateTime
guid.ToString("D"); // Guid
ユーザーが入力した書式をそのまま使う場合は、例外処理も検討します。
C#try
{
Console.WriteLine(value.ToString(format));
}
catch (FormatException)
{
Console.WriteLine("書式指定が正しくありません。");
}
8-3. 期待した日付や数値形式にならない原因
ToString()だけを呼び出すと、実行環境のカルチャ設定に影響されることがあります。
C#DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString());
この結果は、環境によって見え方が変わる可能性があります。期待した形式で固定したい場合は、書式を明示します。
C#Console.WriteLine(date.ToString("yyyy/MM/dd"));
数値も同様です。
C#decimal price = 1234.56m;
Console.WriteLine(price.ToString("N2"));
桁区切りや小数点の記号はカルチャによって変わる場合があります。固定形式で出力したい場合は、InvariantCultureを指定します。
C#using System.Globalization;
Console.WriteLine(price.ToString("F2", CultureInfo.InvariantCulture));
ユーザー表示用なのか、システム連携用なのかによって、書式とカルチャを使い分けることが大切です。
8-4. 小数点や通貨記号が環境によって変わる理由
小数点、桁区切り、通貨記号は、現在のカルチャに依存します。
C#decimal price = 1234.56m;
Console.WriteLine(price.ToString("C"));
日本環境では円記号、アメリカ環境ではドル記号になるなど、環境によって表示が変わる可能性があります。
表示を日本向けに固定したい場合は、ja-JPを指定します。
C#using System.Globalization;
decimal price = 1234.56m;
Console.WriteLine(price.ToString("C", new CultureInfo("ja-JP")));
アメリカ向けならen-USを指定します。
C#Console.WriteLine(price.ToString("C", new CultureInfo("en-US")));
システム内部で処理する値を固定形式にしたい場合は、InvariantCultureを使います。
C#Console.WriteLine(price.ToString("F2", CultureInfo.InvariantCulture));
「環境によって表示が変わって困る」という場合は、カルチャを明示するのが基本です。
8-5. 自作クラスで型名だけが表示される原因
自作クラスでToString()を呼んだときに型名だけが表示されるのは、ToStringをオーバーライドしていないためです。
C#class Customer
{
public string Name { get; set; }
}
Customer customer = new Customer { Name = "Suzuki" };
Console.WriteLine(customer.ToString()); // SampleApp.Customer など
中身を表示したい場合は、ToStringをオーバーライドします。
C#class Customer
{
public string Name { get; set; }
public override string ToString()
{
return $"Customer(Name={Name})";
}
}
C#Customer customer = new Customer { Name = "Suzuki" };
Console.WriteLine(customer.ToString()); // Customer(Name=Suzuki)
ログやデバッグでオブジェクトの内容を確認したい場合は、自作クラスにToStringを実装しておくと便利です。
9. 実務で使えるToStringのサンプル集
9-1. 金額を「1,000円」のように表示する
金額を桁区切り付きで表示するには、N0を使います。
C#int price = 1000;
string text = $"{price.ToString("N0")}円";
Console.WriteLine(text); // 1,000円
decimalでも同じように使えます。
C#decimal price = 1234567m;
string text = $"{price.ToString("N0")}円";
Console.WriteLine(text); // 1,234,567円
日本語表示として明確にしたい場合は、カルチャを指定します。
C#using System.Globalization;
decimal price = 1234567m;
string text = $"{price.ToString("N0", new CultureInfo("ja-JP"))}円";
Console.WriteLine(text); // 1,234,567円
通貨書式Cを使う方法もあります。
C#using System.Globalization;
decimal price = 1000m;
Console.WriteLine(price.ToString("C", new CultureInfo("ja-JP"))); // ¥1,000 など
画面表示で「円」を明示したい場合は、N0に円を付ける書き方が扱いやすいです。
9-2. 日付を「2026年05月26日」のように表示する
日付を日本語形式で表示するには、DateTime.ToStringに書式を指定します。
C#DateTime date = new DateTime(2026, 5, 26);
string text = date.ToString("yyyy年MM月dd日");
Console.WriteLine(text); // 2026年05月26日
月や日をゼロ埋めしたくない場合は、Mとdを使います。
C#DateTime date = new DateTime(2026, 5, 6);
Console.WriteLine(date.ToString("yyyy年M月d日")); // 2026年5月6日
曜日も表示したい場合は、ddddを追加します。
C#using System.Globalization;
DateTime date = new DateTime(2026, 5, 26);
string text = date.ToString("yyyy年MM月dd日 dddd", new CultureInfo("ja-JP"));
Console.WriteLine(text); // 2026年05月26日 火曜日
帳票やメール本文などでは、日付形式を明示しておくと表示崩れを防げます。
9-3. 小数を指定桁数で丸めて表示する
小数を指定桁数で表示したい場合は、FやNを使います。
C#double value = 12.3456;
Console.WriteLine(value.ToString("F2")); // 12.35
Console.WriteLine(value.ToString("F1")); // 12.3
桁区切りも付けたい場合はNを使います。
C#double value = 12345.6789;
Console.WriteLine(value.ToString("N2")); // 12,345.68
ToString("F2")やToString("N2")は表示上の丸めを行います。計算結果そのものを丸めたい場合は、Math.Roundを使います。
C#double value = 12.3456;
double rounded = Math.Round(value, 2);
Console.WriteLine(rounded); // 12.35
Console.WriteLine(rounded.ToString("F2")); // 12.35
画面表示だけならToString("F2")、値そのものを丸めて後続処理に使うならMath.Roundと覚えておくとよいでしょう。
9-4. ログ出力用にオブジェクト情報を整形する
ログ出力では、あとから読んで意味がわかる文字列にすることが重要です。
C#class Payment
{
public int Id { get; set; }
public decimal Amount { get; set; }
public string Status { get; set; }
public DateTime CreatedAt { get; set; }
public override string ToString()
{
return $"Payment(Id={Id}, Amount={Amount:N0}, Status={Status}, CreatedAt={CreatedAt:yyyy-MM-dd HH:mm:ss})";
}
}
使用例です。
C#Payment payment = new Payment
{
Id = 501,
Amount = 9800m,
Status = "Completed",
CreatedAt = new DateTime(2026, 5, 26, 15, 20, 0)
};
Console.WriteLine(payment.ToString());
出力例です。
C#Payment(Id=501, Amount=9,800, Status=Completed, CreatedAt=2026-05-26 15:20:00)
このように、クラス名、プロパティ名、値を含めると、ログを見たときに状況を把握しやすくなります。
9-5. nullでも安全に文字列化する共通メソッド例
nullの可能性がある値を安全に文字列化したい場合は、共通メソッドを作ると便利です。
C#static string ToSafeString(object value)
{
return value?.ToString() ?? string.Empty;
}
使用例です。
C#object value1 = 123;
object value2 = null;
Console.WriteLine(ToSafeString(value1)); // 123
Console.WriteLine(ToSafeString(value2)); // 空文字
デフォルト文字列を指定できるようにするなら、次のようにできます。
C#static string ToSafeString(object value, string defaultValue)
{
return value?.ToString() ?? defaultValue;
}
使用例です。
C#object name = null;
string text = ToSafeString(name, "未設定");
Console.WriteLine(text); // 未設定
拡張メソッドにすることもできます。
C#public static class StringExtensions
{
public static string ToSafeString(this object value)
{
return value?.ToString() ?? string.Empty;
}
}
使用例です。
C#object value = null;
string text = value.ToSafeString();
Console.WriteLine(text); // 空文字
ただし、拡張メソッドを使う場合でも、チーム全体で意図が伝わる命名にすることが大切です。
10. C# ToStringに関するよくある質問
10-1. ToStringはどの型でも使えますか?
C#では、多くの型でToString()を使えます。これは、基本的にすべての型がSystem.Objectを基底としており、Object.ToString()を持っているためです。
C#int number = 123;
DateTime date = DateTime.Now;
bool flag = true;
Console.WriteLine(number.ToString());
Console.WriteLine(date.ToString());
Console.WriteLine(flag.ToString());
ただし、参照型の変数がnullの場合は注意が必要です。
C#object value = null;
Console.WriteLine(value.ToString()); // NullReferenceException
nullの可能性がある場合は、次のように書きます。
C#string text = value?.ToString() ?? "";
10-2. ToString()とToString("N0")の違いは何ですか?
ToString()は、値を通常の形式で文字列化します。
C#int number = 1234567;
Console.WriteLine(number.ToString()); // 1234567
ToString("N0")は、数値を桁区切り付きで、小数点以下0桁の形式にします。
C#int number = 1234567;
Console.WriteLine(number.ToString("N0")); // 1,234,567
Nは数値形式、0は小数点以下の桁数を表します。
C#double value = 1234.567;
Console.WriteLine(value.ToString("N0")); // 1,235
Console.WriteLine(value.ToString("N2")); // 1,234.57
金額や件数を見やすく表示したい場合にN0はよく使われます。
10-3. ToStringでnullを空文字にできますか?
直接null.ToString()のように呼ぶことはできません。参照型がnullの場合、ToString()を呼ぶとNullReferenceExceptionになります。
C#object value = null;
string text = value.ToString(); // NullReferenceException
nullを空文字にしたい場合は、次のように書きます。
C#string text = value?.ToString() ?? "";
または、string.Emptyを使います。
C#string text = value?.ToString() ?? string.Empty;
Convert.ToStringを使う方法もあります。
C#string text = Convert.ToString(value);
nullの可能性がある値を扱う場合は、直接ToString()を呼ばず、安全な書き方を選びましょう。
10-4. ToStringをオーバーライドしないとどうなりますか?
自作クラスでToStringをオーバーライドしない場合、通常は型名が表示されます。
C#class User
{
public string Name { get; set; }
}
User user = new User { Name = "Tanaka" };
Console.WriteLine(user.ToString()); // SampleApp.User など
オブジェクトの中身を表示したい場合は、ToStringをオーバーライドします。
C#class User
{
public string Name { get; set; }
public override string ToString()
{
return $"User(Name={Name})";
}
}
C#User user = new User { Name = "Tanaka" };
Console.WriteLine(user.ToString()); // User(Name=Tanaka)
ログやデバッグで自作クラスの内容を確認したい場合は、ToStringをオーバーライドしておくと便利です。
10-5. ToStringと文字列補間はどちらを使うべきですか?
単体の値を文字列に変換したい場合は、ToStringを使うとわかりやすいです。
C#int number = 123;
string text = number.ToString();
表示形式を指定したい場合も、ToStringが使えます。
C#string text = number.ToString("N0");
一方、文章の中に値を埋め込みたい場合は、文字列補間のほうが読みやすくなります。
C#int price = 1000;
string message = $"価格は{price:N0}円です";
次のようにToString()を連結するより、文字列補間のほうが自然です。
C#string message1 = "価格は" + price.ToString("N0") + "円です";
string message2 = $"価格は{price:N0}円です";
実務では、単体変換にはToString、メッセージ作成には文字列補間を使うのがおすすめです。
まとめ
C#のToStringは、値やオブジェクトを文字列に変換するための基本的なメソッドです。数値、日付、真偽値、enum、Guid、自作クラスなど、さまざまな型で利用できます。
単純な文字列変換であれば、次のように書けます。
C#int number = 123;
string text = number.ToString();
数値や日付では、書式指定を使うことで表示形式を整えられます。
C#int price = 1000;
Console.WriteLine(price.ToString("N0")); // 1,000
DateTime date = new DateTime(2026, 5, 26);
Console.WriteLine(date.ToString("yyyy/MM/dd")); // 2026/05/26
カルチャを指定すれば、通貨、日付、小数点などの地域差にも対応できます。
C#using System.Globalization;
decimal price = 1234.56m;
Console.WriteLine(price.ToString("C", new CultureInfo("ja-JP")));
自作クラスでは、ToStringをオーバーライドすることで、ログやデバッグで見やすい文字列を返せます。
C#public override string ToString()
{
return $"Id={Id}, Name={Name}";
}
また、nullに対して直接ToString()を呼ぶとNullReferenceExceptionが発生するため、null対策も重要です。
C#string text = value?.ToString() ?? "";
ToStringはシンプルなメソッドですが、書式指定、カルチャ、オーバーライド、null対策まで理解すると、実務で安全かつ読みやすいコードを書けるようになります。数値や日付の表示、ログ出力、画面表示など、さまざまな場面で活用していきましょう。

