C#でcharをbyteに変換する方法|文字コードとUnicodeの違いもわかりやすく解説

はじめに

C#でcharbyteに変換したい場面は、文字コードを扱う処理、ファイル入出力、通信、バイナリデータの操作などでよくあります。

ただし、charbyteは似ているようで役割が大きく異なります。C#のcharは「1文字」を表す型であり、byteは「0〜255の整数値」を表す型です。そのため、単純にcharbyteへ変換すればよいとは限りません。

特に注意したいのは、日本語や絵文字などのUnicode文字です。英数字のようなASCII文字であればbyteに変換できるケースがありますが、日本語の文字を1つのbyteに収めることはできません。この場合は、Encoding.UTF8.GetBytesなどを使ってbyte配列に変換する必要があります。

この記事では、C#でcharbyteに変換する方法を、キャスト、Convert.ToByteEncodingの使い方に分けて解説します。あわせて、文字コード、Unicode、UTF-8、ASCIIの違いもわかりやすく説明します。

1. C#でcharをbyteに変換する前に知っておきたい基本

1-1. charとbyteの違い

C#のcharbyteは、どちらも小さなデータを扱う型ですが、意味が異なります。

charは文字を表す型です。たとえば、次のように1文字を格納できます。

C#
char c = 'A';

一方、byteは0〜255までの整数値を表す型です。

C#
byte b = 65;

この例では、char'A'byte65は関係があります。ASCIIコードでは、文字Aのコード値が65だからです。

しかし、charは文字であり、byteは数値です。つまり、'A'65は見た目上は対応していても、型としては別物です。

1-2. C#のcharは1文字を表す16ビットのUnicode文字

C#のcharは、1文字を表す16ビットの型です。内部的にはUnicodeのUTF-16コード単位として扱われます。

たとえば、次のように日本語の文字もcharに格納できます。

C#
char c = 'あ';

charは16ビットなので、0〜65535までの範囲のコード値を持つことができます。

C#
char c = 'A';
int code = c;

Console.WriteLine(code); // 65

このように、charは文字でありながら、内部的には数値のコード値を持っています。

ただし、すべての文字が1つのcharで表せるわけではありません。絵文字など一部の文字は、サロゲートペアと呼ばれる2つのcharで表現されます。そのため、C#で文字コードを扱うときは、charが常に「人間が見る1文字」と完全に一致するわけではない点にも注意が必要です。

1-3. byteは0〜255の数値を表す8ビット型

byteは8ビットの符号なし整数型です。扱える範囲は0〜255です。

C#
byte b1 = 0;
byte b2 = 255;

byteは文字そのものではなく、数値です。ファイル、画像、通信データ、暗号化処理、バイナリデータなどでは、データをbyte単位で扱うことがよくあります。

文字をファイルやネットワークに送る場合も、最終的にはbyte列として扱われます。ただし、そのときは文字コードに従って文字をbyteへ変換する必要があります。

1-4. charをbyteに変換するときに起こりやすい誤解

C#でcharbyteに変換するときによくある誤解は、「1文字だから1byteで表せる」と考えてしまうことです。

たとえば、英字の'A'はASCIIでは1byteで表せます。

C#
char c = 'A';
byte b = (byte)c;

Console.WriteLine(b); // 65

しかし、日本語の'あ'は1byteでは表せません。

C#
char c = 'あ';

この文字をUTF-8で表現すると、複数のbyteが必要になります。

つまり、charbyteに変換したい場合は、次のどちらをしたいのかを先に考える必要があります。

C#
// 文字コード値をbyteにしたいのか
byte b = (byte)'A';

// 文字を文字コードに従ってbyte配列にしたいのか
byte[] bytes = Encoding.UTF8.GetBytes("A");

この違いを理解しておくことが、charbyte変換で失敗しないための重要なポイントです。

2. C#でcharをbyteに変換する主な方法

2-1. キャストでcharをbyteに変換する方法

もっとも単純な方法は、キャストを使ってcharbyteに変換する方法です。

C#
char c = 'A';
byte b = (byte)c;

Console.WriteLine(b); // 65

この方法では、charのコード値をbyteに変換します。

'A'のコード値は65なので、byteに変換すると65になります。

ただし、byteの範囲は0〜255です。charのコード値が255を超える場合、正しく扱えない可能性があります。

2-2. Convert.ToByteでcharをbyteに変換する方法

Convert.ToByteを使ってcharbyteに変換することもできます。

C#
char c = 'A';
byte b = Convert.ToByte(c);

Console.WriteLine(b); // 65

Convert.ToByte(char)も、基本的にはcharのコード値をbyteに変換します。

ただし、コード値がbyteの範囲を超える場合は、OverflowExceptionが発生します。

C#
char c = 'あ';

byte b = Convert.ToByte(c); // OverflowException

キャストの場合は値が切り捨てられる可能性がありますが、Convert.ToByteでは変換できない場合に例外が発生します。そのため、安全にエラーを検出したい場合はConvert.ToByteが便利です。

2-3. Encodingを使ってcharをbyte配列に変換する方法

文字をファイルや通信で扱う場合は、Encodingを使ってbyte配列に変換するのが基本です。

C#
using System.Text;

char c = 'あ';
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));

この方法では、文字コードに従って文字をbyte列に変換します。

たとえば、UTF-8では英字は1byte、日本語は多くの場合3byteで表現されます。

C#
byte[] a = Encoding.UTF8.GetBytes("A");
byte[] japanese = Encoding.UTF8.GetBytes("あ");

Console.WriteLine(a.Length); // 1
Console.WriteLine(japanese.Length); // 3

文字そのものを正しくbyteとして扱いたい場合は、単一のbyteではなくbyte[]を使う必要があります。

2-4. 目的別に使い分けるべき変換方法

C#でcharbyteに変換する方法は、目的によって使い分ける必要があります。

ASCII文字のコード値を取得したいだけなら、キャストで十分な場合があります。

C#
byte b = (byte)'A';

範囲外の文字を検出したい場合は、Convert.ToByteが使えます。

C#
byte b = Convert.ToByte('A');

文字をファイル保存や通信で扱いたい場合は、Encodingを使います。

C#
byte[] bytes = Encoding.UTF8.GetBytes("A");

数字文字を数値として扱いたい場合は、charからbyteへ直接変換するのではなく、文字としての数字を数値に変換します。

C#
char c = '5';
byte number = byte.Parse(c.ToString());

Console.WriteLine(number); // 5

(byte)'5'の結果は5ではなく、ASCIIコードの53になる点に注意してください。

3. キャストでcharをbyteに変換する方法

3-1. charをbyteにキャストする基本コード

C#では、charbyteに暗黙的に変換することはできません。そのため、明示的なキャストが必要です。

C#
char c = 'A';
byte b = (byte)c;

Console.WriteLine(b);

実行結果は次のようになります。

C#
65

これは、文字Aのコード値が65だからです。

次のように、intに変換して確認するとわかりやすくなります。

C#
char c = 'A';

Console.WriteLine((int)c); // 65
Console.WriteLine((byte)c); // 65

charbyteにキャストするということは、文字そのものを変換しているのではなく、文字のコード値をbyte型に変換しているという意味です。

3-2. ASCII文字ならキャストで変換できる理由

ASCII文字は、基本的に0〜127の範囲のコード値で表されます。

たとえば、代表的な文字のコード値は次のようになります。

C#
Console.WriteLine((byte)'A'); // 65
Console.WriteLine((byte)'B'); // 66
Console.WriteLine((byte)'a'); // 97
Console.WriteLine((byte)'0'); // 48

byteは0〜255まで表せるため、ASCII文字のコード値であればbyteの範囲に収まります。

そのため、英数字や一部の記号を扱うだけであれば、キャストによる変換が使える場面があります。

C#
char c = 'Z';

if (c <= byte.MaxValue)
{
byte b = (byte)c;
Console.WriteLine(b);
}

ただし、この方法は「文字コード値を取得したい場合」に限って使うべきです。文字をエンコードしてバイト列にしたい場合は、Encodingを使う方が適切です。

3-3. 日本語やUnicode文字ではキャストが危険な理由

日本語の文字は、ASCII文字の範囲には収まりません。

C#
char c = 'あ';

Console.WriteLine((int)c);

'あ'のコード値は255より大きいため、byteにそのまま収めることはできません。

それにもかかわらずキャストすると、値が切り詰められてしまう可能性があります。

C#
char c = 'あ';
byte b = (byte)c;

Console.WriteLine(b);

この結果は、元の文字'あ'を正しく表す値ではありません。

つまり、(byte)'あ'のような変換をしても、日本語文字を正しくbyteに変換できたことにはなりません。

日本語をbyteに変換したい場合は、次のようにEncodingを使います。

C#
using System.Text;

char c = 'あ';
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));

3-4. オーバーフローやデータ欠落に注意する

charbyteにキャストする場合、checkedを使うと範囲外の変換を検出できます。

C#
char c = 'あ';

try
{
byte b = checked((byte)c);
Console.WriteLine(b);
}
catch (OverflowException)
{
Console.WriteLine("byteの範囲を超えています。");
}

checkedを使わないキャストでは、範囲外の値が切り詰められる可能性があります。

C#
char c = 'あ';
byte b = (byte)c;

このようなコードは、エラーにならずに実行できてしまう場合がありますが、正しい変換結果とは限りません。

安全に処理したい場合は、事前に範囲チェックを行いましょう。

C#
char c = 'A';

if (c <= byte.MaxValue)
{
byte b = (byte)c;
Console.WriteLine(b);
}
else
{
Console.WriteLine("byteに変換できない文字です。");
}

4. Convert.ToByteでcharをbyteに変換する方法

4-1. Convert.ToByteを使った変換コード

Convert.ToByteを使うと、charbyteに変換できます。

C#
char c = 'A';
byte b = Convert.ToByte(c);

Console.WriteLine(b); // 65

このコードでは、charのコード値がbyteに変換されます。

'A'のコード値は65なので、結果は65です。

キャストとの違いは、Convert.ToByteでは範囲外の値を変換しようとしたときに例外が発生する点です。

C#
char c = 'あ';

try
{
byte b = Convert.ToByte(c);
Console.WriteLine(b);
}
catch (OverflowException)
{
Console.WriteLine("byteの範囲を超えています。");
}

このように、Convert.ToByteは変換できないケースを検出したい場合に使いやすい方法です。

4-2. 数字文字を数値に変換したい場合の注意点

数字文字を扱う場合は、特に注意が必要です。

たとえば、次のコードを見てください。

C#
char c = '5';
byte b = Convert.ToByte(c);

Console.WriteLine(b);

この結果は、数値の5ではありません。

文字'5'の文字コード値は53なので、結果は53になります。

C#
char c = '5';

Console.WriteLine((byte)c); // 53
Console.WriteLine(Convert.ToByte(c)); // 53

数字文字を数値として扱いたい場合は、次のように変換します。

C#
char c = '5';
byte number = byte.Parse(c.ToString());

Console.WriteLine(number); // 5

または、char.GetNumericValueを使う方法もあります。

C#
char c = '5';
double value = char.GetNumericValue(c);

byte number = (byte)value;

Console.WriteLine(number); // 5

ただし、char.GetNumericValueは戻り値がdoubleであるため、単純な数字文字だけを扱う場合はbyte.Parseの方がわかりやすいです。

4-3. 文字コード値と数値変換の違い

charbyteに変換するときは、「文字コード値を取得する」のか「数字として変換する」のかを区別する必要があります。

次の2つは意味が違います。

C#
char c = '7';

byte code = (byte)c;
byte number = byte.Parse(c.ToString());

Console.WriteLine(code); // 55
Console.WriteLine(number); // 7

codeには文字'7'の文字コード値が入ります。

一方、numberには数値としての7が入ります。

この違いを理解していないと、計算処理でバグが発生しやすくなります。

C#
char c = '3';

byte wrong = (byte)c;
byte correct = byte.Parse(c.ToString());

Console.WriteLine(wrong + 1); // 52
Console.WriteLine(correct + 1); // 4

(byte)cは文字コード値を取得する処理であり、数字文字を数値にする処理ではありません。

4-4. 変換できないケースと例外処理

Convert.ToByte(char)では、charのコード値が0〜255の範囲を超えるとOverflowExceptionが発生します。

C#
char c = '漢';

try
{
byte b = Convert.ToByte(c);
Console.WriteLine(b);
}
catch (OverflowException ex)
{
Console.WriteLine("変換できません。");
Console.WriteLine(ex.Message);
}

日本語や多くのUnicode文字は、byteの範囲に収まりません。

そのため、Convert.ToByteを使う場合は、例外処理を用意しておくと安全です。

また、事前に範囲チェックをする方法もあります。

C#
char c = 'A';

if (c <= byte.MaxValue)
{
byte b = Convert.ToByte(c);
Console.WriteLine(b);
}
else
{
Console.WriteLine("byteに変換できない文字です。");
}

変換できない文字を扱う可能性がある場合は、単一のbyteではなく、Encodingを使ってbyte配列に変換することを検討しましょう。

5. Encodingを使ってcharをbyte配列に変換する方法

5-1. Encoding.UTF8.GetBytesで変換する基本コード

文字を正しくbyteに変換したい場合は、System.Text.Encodingを使います。

特に、現在のアプリケーション開発ではUTF-8を使う場面が多いため、Encoding.UTF8.GetBytesがよく使われます。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
char c = 'A';
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));
}
}

実行結果は次のようになります。

C#
65

英字のAはUTF-8でも1byteで表されます。

日本語の場合は、次のようになります。

C#
char c = 'あ';
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));
Console.WriteLine(bytes.Length);

UTF-8では、日本語の'あ'は複数のbyteで表現されます。

重要なのは、Encoding.UTF8.GetBytesの戻り値がbyteではなくbyte[]であることです。

C#
byte[] bytes = Encoding.UTF8.GetBytes("あ");

文字を文字コードに従って変換する場合、結果が1byteとは限らないため、配列で受け取る必要があります。

5-2. Encoding.ASCIIで変換する場合

ASCIIとして変換したい場合は、Encoding.ASCIIを使います。

C#
using System.Text;

char c = 'A';
byte[] bytes = Encoding.ASCII.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes)); // 65

ASCIIでは、英数字や基本的な記号を1byteで表現できます。

C#
Console.WriteLine(Encoding.ASCII.GetBytes("ABC").Length); // 3

ただし、ASCIIは日本語を表現できません。

C#
byte[] bytes = Encoding.ASCII.GetBytes("あ");
Console.WriteLine(string.Join(", ", bytes));

ASCIIで表現できない文字は、通常、代替文字に置き換えられます。そのため、日本語をASCIIで変換すると、元の文字情報が失われます。

日本語や多言語の文字を扱う場合は、ASCIIではなくUTF-8を使うのが一般的です。

C#
byte[] bytes = Encoding.UTF8.GetBytes("あ");

5-3. Encoding.Unicodeで変換する場合

C#では、Encoding.Unicodeを使うとUTF-16リトルエンディアンとして文字列をbyte配列に変換できます。

C#
using System.Text;

char c = 'A';
byte[] bytes = Encoding.Unicode.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));

Encoding.Unicodeでは、基本的なcharは2byteで表現されます。

たとえば、'A'は次のような2byteになります。

C#
65, 0

日本語の'あ'も、UTF-16では基本的に2byteで表されます。

C#
char c = 'あ';
byte[] bytes = Encoding.Unicode.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));
Console.WriteLine(bytes.Length); // 2

ただし、絵文字など一部の文字はサロゲートペアとして扱われるため、UTF-16では4byteになることがあります。

5-4. 文字コードによってbyte数が変わる仕組み

同じ文字でも、使用する文字コードによってbyte数は変わります。

C#
using System;
using System.Text;

string text = "あ";

byte[] utf8 = Encoding.UTF8.GetBytes(text);
byte[] unicode = Encoding.Unicode.GetBytes(text);

Console.WriteLine($"UTF-8: {utf8.Length} bytes");
Console.WriteLine($"Unicode: {unicode.Length} bytes");

UTF-8では、日本語は多くの場合3byteで表されます。

一方、Encoding.Unicode、つまりUTF-16では、多くの基本的な日本語文字は2byteで表されます。

英字の場合は次のようになります。

C#
string text = "A";

Console.WriteLine(Encoding.UTF8.GetBytes(text).Length); // 1
Console.WriteLine(Encoding.Unicode.GetBytes(text).Length); // 2
Console.WriteLine(Encoding.ASCII.GetBytes(text).Length); // 1

このように、charbyteに変換するときは、「どの文字コードで変換するのか」を明確にする必要があります。

ファイル保存、API通信、Webアプリケーション、JSONなどではUTF-8を使うケースが多いため、迷った場合はまずUTF-8を検討するとよいでしょう。

6. Unicode・UTF-8・ASCIIの違いをわかりやすく解説

6-1. Unicodeとは何か

Unicodeとは、世界中の文字に番号を割り当てるための仕組みです。

英字、日本語、記号、絵文字など、多くの文字にはUnicode上のコードポイントが割り当てられています。

たとえば、文字AにはU+0041というコードポイントがあります。

C#
char c = 'A';
Console.WriteLine($"U+{(int)c:X4}"); // U+0041

日本語のにもUnicodeのコードポイントがあります。

C#
char c = 'あ';
Console.WriteLine($"U+{(int)c:X4}");

Unicodeは文字に番号を付けるための体系であり、実際にメモリやファイル上で何byteになるかは、UTF-8やUTF-16などのエンコーディングによって決まります。

6-2. UTF-8とは何か

UTF-8は、Unicode文字をbyte列として表現するための文字エンコーディングの一つです。

UTF-8の特徴は、文字によって必要なbyte数が変わることです。

英数字などのASCII範囲の文字は1byteで表されます。

C#
byte[] bytes = Encoding.UTF8.GetBytes("A");
Console.WriteLine(bytes.Length); // 1

日本語は多くの場合3byteになります。

C#
byte[] bytes = Encoding.UTF8.GetBytes("あ");
Console.WriteLine(bytes.Length); // 3

絵文字などは4byteになることがあります。

C#
byte[] bytes = Encoding.UTF8.GetBytes("😀");
Console.WriteLine(bytes.Length); // 4

UTF-8はWeb、ファイル、API通信などで広く使われています。そのため、C#で文字をbyte配列に変換する場合、UTF-8を選ぶことが多いです。

6-3. ASCIIとは何か

ASCIIは、英数字や基本的な記号を扱うための古い文字コードです。

ASCIIでは、文字は0〜127の範囲の数値で表されます。

たとえば、次のような対応があります。

C#
Console.WriteLine((int)'A'); // 65
Console.WriteLine((int)'a'); // 97
Console.WriteLine((int)'0'); // 48

ASCII文字は1byteで表せるため、charbyteにキャストしても値が収まります。

C#
char c = 'A';
byte b = (byte)c;

Console.WriteLine(b); // 65

ただし、ASCIIでは日本語を表現できません。そのため、日本語や多言語対応が必要なアプリケーションでは、ASCIIではなくUTF-8を使うのが一般的です。

6-4. C#のcharとUnicodeの関係

C#のcharは、Unicode文字を扱うための型です。正確には、UTF-16の1コード単位を表します。

通常の英字や日本語の多くは、1つのcharで表せます。

C#
char a = 'A';
char j = 'あ';

しかし、絵文字のように1つのcharでは表せない文字もあります。

C#
string emoji = "😀";

Console.WriteLine(emoji.Length); // 2

このように、見た目は1文字でも、C#のstring.Lengthでは2になることがあります。これは、UTF-16のサロゲートペアとして2つのcharで表されているためです。

そのため、charを扱うときは、「C#のcharは必ずしも見た目上の1文字と同じではない」という点を理解しておくとよいでしょう。

6-5. 日本語文字が1byteで表せない理由

byteは0〜255までの256通りの値しか表せません。

一方、日本語にはひらがな、カタカナ、漢字、記号など非常に多くの文字があります。256通りだけでは、日本語の文字をすべて表現することはできません。

そのため、日本語を扱うには複数のbyteを組み合わせて表現する必要があります。

たとえば、UTF-8では'あ'は複数のbyteで表されます。

C#
byte[] bytes = Encoding.UTF8.GetBytes("あ");

Console.WriteLine(string.Join(", ", bytes));
Console.WriteLine(bytes.Length); // 3

つまり、日本語のcharを単一のbyteに変換しようとするのは、基本的には正しくありません。

日本語を扱う場合は、次のようにbyte[]として扱います。

C#
byte[] bytes = Encoding.UTF8.GetBytes("こんにちは");

7. charをbyteに変換するサンプルコード集

7-1. 英数字のcharをbyteに変換するコード

英数字のcharを文字コード値としてbyteに変換する場合は、キャストが使えます。

C#
char c = 'A';
byte b = (byte)c;

Console.WriteLine(b); // 65

複数の英数字を処理する場合は、次のように書けます。

C#
char[] chars = { 'A', 'B', 'C', '1', '2', '3' };

foreach (char c in chars)
{
byte b = (byte)c;
Console.WriteLine($"{c} -> {b}");
}

出力例は次のようになります。

C#
A -> 65
B -> 66
C -> 67
1 -> 49
2 -> 50
3 -> 51

数字文字を数値として扱いたい場合は、キャストではなくbyte.Parseを使います。

C#
char c = '8';
byte number = byte.Parse(c.ToString());

Console.WriteLine(number); // 8

7-2. 日本語文字をbyte配列に変換するコード

日本語文字を扱う場合は、Encoding.UTF8.GetBytesを使ってbyte配列に変換します。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
char c = 'あ';
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

Console.WriteLine(string.Join(", ", bytes));
Console.WriteLine($"{bytes.Length} bytes");
}
}

文字列全体を変換する場合は、charではなくstringのまま変換します。

C#
using System.Text;

string text = "こんにちは";
byte[] bytes = Encoding.UTF8.GetBytes(text);

Console.WriteLine(string.Join(", ", bytes));

日本語をファイルに保存したり、通信で送信したりする場合は、このように文字コードを指定してbyte[]へ変換するのが基本です。

7-3. byte配列から文字に戻すコード

Encodingを使ってbyte配列に変換した文字は、同じエンコーディングを使って文字列に戻します。

C#
using System;
using System.Text;

class Program
{
static void Main()
{
string text = "あ";
byte[] bytes = Encoding.UTF8.GetBytes(text);

string restored = Encoding.UTF8.GetString(bytes);

Console.WriteLine(restored); // あ
}
}

ここで重要なのは、変換時と復元時で同じ文字コードを使うことです。

C#
byte[] bytes = Encoding.UTF8.GetBytes("あ");

string correct = Encoding.UTF8.GetString(bytes);
string wrong = Encoding.ASCII.GetString(bytes);

Console.WriteLine(correct);
Console.WriteLine(wrong);

UTF-8で変換したbyte配列をASCIIとして読み込むと、文字化けの原因になります。

7-4. 変換結果を確認するデバッグコード

charbyteの変換結果を確認したい場合は、コード値や16進数を出力するとわかりやすくなります。

C#
char c = 'A';

Console.WriteLine($"char: {c}");
Console.WriteLine($"int: {(int)c}");
Console.WriteLine($"byte: {(byte)c}");
Console.WriteLine($"hex: 0x{(int)c:X4}");

UTF-8のbyte配列を16進数で確認するコードは次のとおりです。

C#
using System;
using System.Text;

string text = "あ";
byte[] bytes = Encoding.UTF8.GetBytes(text);

foreach (byte b in bytes)
{
Console.WriteLine($"0x{b:X2}");
}

出力を1行で確認したい場合は、次のように書けます。

C#
string hex = BitConverter.ToString(bytes);
Console.WriteLine(hex);

BitConverter.ToStringを使うと、byte配列の中身を確認しやすくなります。

8. charとbyte変換でよくあるエラーと対処法

8-1. Cannot implicitly convert type char to byteの原因

C#で次のようなコードを書くと、コンパイルエラーになります。

C#
char c = 'A';
byte b = c;

エラー内容は次のようなものです。

C#
Cannot implicitly convert type 'char' to 'byte'

これは、charからbyteへの暗黙的な変換が許可されていないためです。

charは16ビット、byteは8ビットです。charの値がbyteの範囲に収まらない可能性があるため、C#では自動変換されません。

明示的に変換するには、キャストを使います。

C#
char c = 'A';
byte b = (byte)c;

ただし、範囲外の文字を扱う場合は注意が必要です。

C#
char c = 'あ';
byte b = (byte)c; // データが欠落する可能性がある

安全に処理するなら、範囲チェックを行いましょう。

C#
char c = 'A';

if (c <= byte.MaxValue)
{
byte b = (byte)c;
Console.WriteLine(b);
}

8-2. OverflowExceptionが発生する原因

Convert.ToByte(char)を使ったときに、OverflowExceptionが発生することがあります。

C#
char c = 'あ';
byte b = Convert.ToByte(c);

これは、charのコード値がbyteの範囲である0〜255を超えているためです。

対処法としては、事前に範囲を確認します。

C#
char c = 'あ';

if (c <= byte.MaxValue)
{
byte b = Convert.ToByte(c);
Console.WriteLine(b);
}
else
{
Console.WriteLine("byteの範囲を超えています。");
}

文字そのものを正しくbyte化したい場合は、Convert.ToByteではなくEncodingを使います。

C#
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

8-3. 文字化けが発生する原因

文字化けの主な原因は、エンコードとデコードで異なる文字コードを使っていることです。

たとえば、UTF-8でbyte配列に変換した文字列を、ASCIIとして読み込むと正しく復元できません。

C#
using System.Text;

string text = "こんにちは";
byte[] bytes = Encoding.UTF8.GetBytes(text);

string wrong = Encoding.ASCII.GetString(bytes);
Console.WriteLine(wrong);

正しく戻すには、同じUTF-8を使います。

C#
string correct = Encoding.UTF8.GetString(bytes);
Console.WriteLine(correct);

ファイルや通信で文字列を扱う場合は、送信側と受信側で文字コードをそろえることが重要です。

C#
byte[] bytes = Encoding.UTF8.GetBytes("こんにちは");
string text = Encoding.UTF8.GetString(bytes);

8-4. 期待したbyte値にならないときの確認ポイント

charbyteに変換した結果が期待と違う場合は、まず何を変換したいのかを確認しましょう。

たとえば、次のコードでは結果は5ではなく53です。

C#
char c = '5';
byte b = (byte)c;

Console.WriteLine(b); // 53

これは、文字'5'のコード値を取得しているためです。

数値としての5が欲しい場合は、次のようにします。

C#
char c = '5';
byte b = byte.Parse(c.ToString());

Console.WriteLine(b); // 5

また、日本語文字をbyteにキャストしている場合は、データが欠落している可能性があります。

C#
char c = '漢';
byte b = (byte)c;

このような場合は、Encoding.UTF8.GetBytesを使ってbyte配列に変換します。

C#
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

確認ポイントは次のとおりです。

C#
char c = 'A';

Console.WriteLine($"文字: {c}");
Console.WriteLine($"コード値: {(int)c}");
Console.WriteLine($"byte範囲内: {((int)c <= byte.MaxValue)}");

文字コードの問題か、数値変換の問題かを切り分けることが大切です。

9. 目的別|charをbyteに変換する正しい選び方

9-1. ASCII文字のコード値を取得したい場合

ASCII文字のコード値を取得したい場合は、キャストを使えます。

C#
char c = 'A';
byte b = (byte)c;

Console.WriteLine(b); // 65

ただし、対象がASCII文字であることを確認してから変換すると安全です。

C#
char c = 'A';

if (c <= 127)
{
byte b = (byte)c;
Console.WriteLine(b);
}
else
{
Console.WriteLine("ASCII文字ではありません。");
}

英数字や基本的な記号だけを扱う処理であれば、この方法で十分な場合があります。

9-2. 文字をファイルや通信で扱いたい場合

文字をファイルに保存したり、ネットワークで送信したりする場合は、Encodingを使ってbyte配列に変換します。

C#
using System.Text;

string text = "Hello";
byte[] bytes = Encoding.UTF8.GetBytes(text);

日本語を含む場合も、UTF-8を使えば正しく変換できます。

C#
string text = "こんにちは";
byte[] bytes = Encoding.UTF8.GetBytes(text);

復元するときは、同じ文字コードを使います。

C#
string restored = Encoding.UTF8.GetString(bytes);

ファイルや通信で文字を扱う場合、単一のbyteに変換するのではなく、byte[]として扱うのが基本です。

9-3. 数字文字を数値として扱いたい場合

数字文字を数値として扱いたい場合は、キャストやConvert.ToByte(char)ではなく、byte.Parseなどを使います。

C#
char c = '9';
byte number = byte.Parse(c.ToString());

Console.WriteLine(number); // 9

安全に変換したい場合は、byte.TryParseを使います。

C#
char c = '9';

if (byte.TryParse(c.ToString(), out byte number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値に変換できません。");
}

(byte)'9'は数値の9ではなく、文字コード値の57です。

C#
Console.WriteLine((byte)'9'); // 57

数字文字を計算に使う場合は、この違いに注意しましょう。

9-4. 日本語や絵文字を扱う場合

日本語や絵文字を扱う場合は、単一のbyteに変換しようとしないことが重要です。

日本語は1byteでは表せません。

C#
char c = 'あ';
byte[] bytes = Encoding.UTF8.GetBytes(c.ToString());

絵文字の場合は、charではなくstringとして扱う方が安全です。

C#
string emoji = "😀";
byte[] bytes = Encoding.UTF8.GetBytes(emoji);

Console.WriteLine(bytes.Length); // 4

絵文字はC#のchar 1つでは表せない場合があります。

C#
string emoji = "😀";
Console.WriteLine(emoji.Length); // 2

そのため、日本語や絵文字を含む文字列を処理する場合は、char単位ではなくstring全体をEncoding.UTF8.GetBytesで変換するのがおすすめです。

C#
string text = "こんにちは😀";
byte[] bytes = Encoding.UTF8.GetBytes(text);

string restored = Encoding.UTF8.GetString(bytes);

Console.WriteLine(restored);

まとめ

C#でcharbyteに変換する方法には、主にキャスト、Convert.ToByteEncodingの3つがあります。

ASCII文字のコード値を取得したい場合は、次のようにキャストを使えます。

C#
char c = 'A';
byte b = (byte)c;

範囲外の値を検出したい場合は、Convert.ToByteを使います。

C#
char c = 'A';
byte b = Convert.ToByte(c);

ただし、日本語やUnicode文字を扱う場合、単一のbyteに変換するのは適切ではありません。文字を正しくbyte化するには、Encodingを使ってbyte配列に変換します。

C#
byte[] bytes = Encoding.UTF8.GetBytes("あ");

また、数字文字を数値として扱いたい場合は、(byte)'5'ではなく、byte.Parseなどを使います。

C#
char c = '5';
byte number = byte.Parse(c.ToString());

charbyteに変換するときは、次の点を意識することが大切です。

C#
// 文字コード値が欲しい
byte code = (byte)'A';

// 数字としての値が欲しい
byte number = byte.Parse('5'.ToString());

// 文字を文字コードでbyte列にしたい
byte[] bytes = Encoding.UTF8.GetBytes("あ");

C#のcharは16ビットのUnicode文字、byteは8ビットの数値です。この違いを理解しておけば、文字化け、オーバーフロー、データ欠落などのトラブルを避けながら、目的に合った正しい変換方法を選べます。