*

C#でバッファの内容を表示する処理を実装してみた-
データ型に従って動的に書式を設定する

公開日: : C#

どもです。

最近、C#でバッファ/配列の値をコンソールに表示したい、という場面がよく発生します。
その場面は、基本的に一過性なので、テキトーに配列の内容を表示させる関数を実装してしのいでいました。
しかし、その場面が増えきて、別のツールを作っている場合だったり、さらにデータ型が違っているために、過去に実装した関数が流用できなかったりと、中々うまくいかないことが多くなりました。
そこで「バッファ/配列の値をコンソールに表示」するための処理を、汎用性を持たせて実装してみました。
今回のエントリは、この実装の中でぶつかった問題とその解決方法について書きます。

1.実装した処理の内容

今回実装した処理は、ざっくりですが、以下の内容になります。

  • 表示は16進数で、接頭辞「0x」をつける
  • 1行に表示するデータ数は、16コ
  • 列の先頭に、何行目なのかを表示する
  • 列ヘッダをつける

2.ぶつかった問題

C#で「16進数で値を表示する」といった場合、私はよく以下のように実装します。

このように実装してる場合に問題になるのは、表示するデータの長さです。
上記の例では、「X4」の「4」がそれに当たります。
即ち、データ型がbyteの場合には「X2」、ushort型の場合には「X4」、ulong型の場合には「X8」としたいです。
各データ型ごとに関数をオーバーロードで実装する、という方法もあります。
具体的には、下記のような関数になります。

しかし、これではバグがあった場合の修正が大変など、保守の面で問題があります。
そのため、データ型に従って(「2」や「4」といった)「データの長さ」を引数で渡すのは、「イケていない」です。

3.ぶつかった問題の解決

では、この問題をどのように解決するか?
それは、「templateを使用する」です。
…まぁ、当たり前といえば当たり前の解決方法ですね。
バッファのデータ型をtemplateの型で指定して、あとは関数内部でデータ型のサイズ(バイト単位)を取得し、それに従って表示する書式を作成する、という方法です。

3.1.データ型のサイズの取得

C#では、データ型に対するサイズは「sizeof演算子」で取得できます。
ただし、この演算子を使用する際には、いくつか制限/上限があります。

3.1.1.制限事項1:unsafe

1つ目の制限事項は、「unsafe」です。
sizeof演算子を使用する際には、unsafeコンテキストが必要です。
unsafeコンテキストの詳細については、Microsoftの公式HPを参照してください。
プリミティブなデータ型、簡単に言うとコンパイル時にデータ型が判定、定数に評価される型であれば、unsafeコンテキストは必要ありません。
しかし、templateを使用する際には、データ型が判定できません。
そのため、unsafeコンテキストが必要になります。
なお「unsafe」は、関数全体とsizeof演算子を使用する範囲のみ、いずれにも設定が可能です。
即ち、以下の2通りの実装が可能です。

3.1.2.制限事項2:unmanaged

2つ目の制限事項は、「unmanaged」です。
sizeof演算子の引数は、アンマネージド型、またはアンマネージド型に制限される型パラメータである必要があります。
そのため、templateのデータ型をunmanagedに制限しなければなりません。
template型をunmanaged型に制限するためには、関数を以下のように実装します。

ここでの「where」は「ジェネリック型制約」と呼ばれます。
whereの詳細は、Microsoftの公式HPを参照してください。

3.2.データ型のサイズの書式への反映

データ型のサイズが取得できたところで、この「サイズ」を書式にどのように反映するか、です。
この解決方法は、実は簡単です、
このエントリでも、すでに登場しています。
それは、「文字列補完書式」です。
即ち、「文字列補完書式を使用して、文字列の書式を作成」します。
説明よりも、実装を示した方が分かりやすいかと思います。

「文字列補完書式を使用して、文字列の書式を作成」しているのが、以下のコード。

文字列補完書式では、「{」は2回重ねることでエスケープされ、1つの「{」となります。
そのため、仮に変数charNumOfTが「2」だとしたら、上記コードの変数formatには、「{0:X2}」が格納されます。
後は、stringのformatメソッドを使用することで、bufferの値をコンソールに表示ができます。

4.実装

それでは、実装です。

コレが、今回実装したコードの全てです。
この関数は、以下のようにして使用します。

実行結果は、下図のようになります。
cs_buffer_viewer_001
次に、変数bufferのデータ型をushortからbyteに変更して実行すると、結果は下図になります。
cs_buffer_viewer_002
このように、データ型の異なるバッファの内容を、コードを変更することなく表示できていることが確認できました。

5.まとめ

今回は、templateと文字列補完を使用して、データ型に従って動的に書式を設定する実装について書きました。
また、この方法の適用して、型の異なるバッファ/配列の内容を、コードを変更することなく表示する方法を書きました。

配列の値を表示するのは、デバッグの時くらいしかないと思います。
しかし、デバッグの度にブレークポイントでプログラムを一時停止して、別途メモリウィンドウを表示してデータを確認する、ということを毎回行うのは効率が悪いです。
そのため、常にバッファの内容を表示できるようにすることでデータを簡単に確認できるようにして、デバッグの効率を向上・改善できれるます。

今回のエントリが、同じような問題を抱えているヒトの助けになれば、幸いです。

ではっ!

関連記事

c_sharp_eye_catch

セル内の「取り消し線で消された文字列」を削除してみた

どもです。 今回は、C#/OpenXmlの組み合わせで、エクセルのセル内の文字列から 「取り

記事を読む

c_sharp_eye_catch

セルに「取り消し線」が設定されているかを判定してみた

どもです。 前回、前々回と、エクセルのセル内の文字列から、「取り消し線」が設定された文字列を削

記事を読む

Splash

EV3開発サポートツール(3)-Ev3Controller

どもです。 今回は、以前ちらりと紹介した、Ev3のモーターの出力を調整するアプリケーションについて

記事を読む

MindStormControl_SprachScreen

EV3開発サポートツール(2)-C#のユーザーコントロール開発(2つ目)

どもです。 前回に引き続き、今回もC#/WPFでの独自UI(ユーザーコントロール)の作成についての

記事を読む

c_sharp_eye_catch

Windowsでのカバレッジ測定-OpenCoverageを使ってみた

どもです。 以前、OpenCppCoverageを使用してWindows上でカバレッジ測定する方法

記事を読む

toppers

C言語でEV3開発(26)-EV3で機械学習(1)-QLearningをC#に委譲してみた

どもです。 前回の投稿では、Q-LearningをEV3本体に実装してみたら、メモリが足りなくて動

記事を読む

MindStormControl_SprachScreen

EV3開発サポートツール(1)-C#のユーザーコントロール開発

どもです。 突然ですが、今回はC#に関するエントリになります。 具体的には、C#/WPFで、独自

記事を読む

c_sharp_eye_catch

セル内の「取り消し線で消された文字列」の削除を簡単にしてみた

どもです。 前回、C#/OpenXmlを用いて、エクセルのセル内の文字列から「打消し線で消され

記事を読む

c_sharp_eye_catch

外部からMariaDbにアクセスする(2)-C#からMariaDbにアクセスする。

どもです。 前回のエントリで、外部からMariaDbにアクセスするための、データベース側の設定

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

c_sharp_eye_catch
セルに「取り消し線」が設定されているかを判定してみた

どもです。 前回、前々回と、エクセルのセル内の文字列から、「取り

c_sharp_eye_catch
セル内の「取り消し線で消された文字列」の削除を簡単にしてみた

どもです。 前回、C#/OpenXmlを用いて、エクセルのセル内

c_sharp_eye_catch
セル内の「取り消し線で消された文字列」を削除してみた

どもです。 今回は、C#/OpenXmlの組み合わせで、エクセル

c_sharp_eye_catch
C#でバッファの内容を表示する処理を実装してみた-
データ型に従って動的に書式を設定する

どもです。 最近、C#でバッファ/配列の値をコンソールに表示した

arduino_relay_switch_003_self_preservation_circuit_eye_catch
Arduinoでリレースイッチ(3)-自己保存回路

どもです。 前回の記事で、リレースイッチ「AE-G5V-DRV」

→もっと見る

PAGE TOP ↑