C# 初級講座 |
![]() ![]() ![]() ![]() |
2022/5/15
この記事が対象とする製品・バージョン
![]() |
Visual Studio 2022 | ◎ | 対象です。 |
![]() |
Visual Studio 2019 | ◎ | 対象です。 |
![]() |
Visual Studio 2017 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio 2015 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio 2013 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio 2012 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio 2010 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio 2008 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio 2005 | △ | 対象ですが参考にはなります。 |
![]() |
Visual Studio.NET 2003 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio.NET (2002) | △ | 対象外ですが参考にはなります。 |
Visual Studio Code | △ | 対象外ですが参考にはなります。 |
目次
今回はクラスのメソッドを呼び出す方法理解するため練習です。知識が身についているか試してみましょう。
Windows フォーム アプリ でアプリケーションを作成して、練習問題で出題しているプログラムを作ってください。
Google検索などすると練習にならないので使わないようにしてください。
C#やフレームワークのヘルプ(Microsoft Docsのリファレンス)を見る力も養いたいので、リファレンスを見るのはOKです。見るべきリファレンスがある場合は問題の中にリンクを示します。リファレンスを自分で読み解かないと解けないようになっています。リファレンス内のリンクをクリックして別のページに飛んでもOKです。
私は少しだけ難しめに問題を作ったつもりです。教室で目の前の生徒に教えているわけではないので、私の意図通りの難易度になっているかはちょっとわからないのですが、もし、よくわからなかったとしたら、終わってから自分で軽く調べてみるくらいは良いのですが、あまりこだわりすぎてここで勉強を立ち止まるよりは次へ進んでいくことをおすすめします。
MathクラスのPowメソッドは、累乗(累乗)を計算する機能です。
累乗とは同じ数字を何個かけ算するかを表しています。たとえば、2を3個かけ算すると答えは8です。これを「2の3乗は8」と表現し、2の右上に小さい3を書いて表現します。
x の y乗 とは、x を y個かけ算するという意味で、3 の 2乗 は 9、 1 の 12乗 は 1 です。
それでは、MathクラスのPowメソッドを使って、6の7乗を計算するプログラムを書いてください。
答えはMessageBox.Show を使って画面に表示してください。
Math.Powの詳しい説明が必要であれば下記のリファレンスを参照してください。
https://docs.microsoft.com/ja-jp/dotnet/api/system.math.pow
解答例と解説を見るには、下にスクロールしてください。
↓ もうちょっと下です。
double answer = Math.Pow(6, 7);
MessageBox.Show(answer.ToString());
簡単な静的メソッドの呼び出しです。
呼び出し方はリファレンスから読み取れます。
Pow の定義には static がついているので、これが静的メソッドであるということがわかります。。
静的メソッドなので クラス名.メソッド名 の形で呼び出せます。この場合は Math.Pow で呼び出せるということです。
名前空間は System なのでデフォルトで省略可能です。省略できるかわからなければ、省略せずに System.Math と書いてもOKです。これでもエラーにはならず正常に実行されます。Visual Studioは「System」の部分をグレーで表示します。グレーで表示される名前空間は省略して良いという意味です。
戻り値はdoubleなので、double型の変数で戻り値を受け取ります。
解答例の double の部分を代わりに var としても構いません。宣言と同時に代入しているので、C#が個の変数の型が double であることを推論できるからです。
MessageBox.Show の引数は文字列型でないといけないので ToStringメソッドを呼び出して double型のanswerを文字列に変換する必要があります。
このプログラムをそもそもどこに書けばよいかわからないという方は入門講座をご覧になってください。
StringInfoクラスのLengthInTextElementsプロパティ(読み方:StringInfo = ストリングインフォ、LengthInTextElements = レンクスインテキストエレメンツ)は文字列に含まれる文字の数を表します。
似た機能にStringクラスのLengthプロパティ(読み方:Length = レンクス)や、StringsモジュールのLenメソッド(読み方:Len = レン)がありますが、絵文字や難しい文字(Unicodeの第2面以降の文字)を正しく数えることができません。
たとえば、東京タワーを表す絵文字 🗼 は、1文字なのに2文字と数えてしまいます。
string tokyoTower = "🗼に行きたい!"; //7文字
int length = tokyoTower.Length;
MessageBox.Show(length.ToString()); //8 と表示される。
StringInfoクラスのLengthInTextElementsプロパティは絵文字や難しい文字が含まれていても正確な文字数を表します。
これを使って上記の例を修正し、7 が表示されるようにしてください。
StringInfoクラスの詳しい説明は下記のリファレンスを参照してください。
https://docs.microsoft.com/ja-jp/dotnet/api/system.globalization.stringinfo
LengthInTextElementsプロパティのリファレンスはこのリファレンス内のプロパティ欄内にあるリンクをクリックして表示できます。
解答例と解説を見るには、下にスクロールしてください。
↓ もうちょっと下です。
string tokyoTower = "🗼に行きたい!"; //7文字
var info = new System.Globalization.StringInfo(tokyoTower);
int length = info.LengthInTextElements;
MessageBox.Show(length.ToString()); //7 と表示される。
非静的プロパティの呼び出しです。
呼び出し方はリファレンスから読み取れます。
LengthInTextElementsプロパティはstaticで定義されていないので、非静的メソッドです。
つまり、インスタンスを作成して、インスタンスからこのプロパティにアクセスする必要があります。
インスタンスを作成するにはコンストラクターを呼び出します。
StringInfoクラスのリファレンスを見ると2つのコンストラクターが存在するのがわかります。
2つ目のコンストラクターは対象の文字列を指定できるようなので、これを使って 「🗼に行きたい!」 を指定するのが簡単そうです。
記載されている説明は何を言っているのか少しわかりにくいですが、英語の翻訳の質が悪いのです。「指定した文字列向けに StringInfoクラスの新しいインスタンスを初期化します。」という意味だと思ってください。日本語の意味が分かりにくい説明はしばしばあります。慣れてくると翻訳の質の問題と気が付けるかもしれません。英語がわかるなら英語版を見てみるのも手です。
コンストラクターを呼び出してインスタンスを受け取るには newを使います。
名前空間System.Globalizationは既定では省略できないので、名前空間を指定することになります。直接名前空間を記述する他ににusingキーワードを使う方法もあります。usingキーワードについてはまだ説明していません。回答例では1回呼び出すだけなので名前空間を記述することにしました。
なお、1つ目のコンストラクターでインスタンスを作成した場合、対象の文字列を指定するには、Stringプロパティを使用します。
これを使って下記のようにプログラムしてもOKです。
string tokyoTower = "🗼に行きたい!"; //7文字
var info = new System.Globalization.StringInfo();
info.String = tokyoTower;
int length = info.LengthInTextElements;
MessageBox.Show(length.ToString()); //7 と表示される。
ZipFileクラスのCreateFromDirectoryメソッド (読み方:ZipFile = ジップファイル、CreateFromDirectory = クリエイトフロムディレクトリー)は、フォルダーをまるごと圧縮してzipファイルを作成してくれる便利なメソッドです。
このメソッドを使って、zipファイルを作ってください。
説明を簡単にするために圧縮するフォルダーとzipファイル名は次のようにします。(変更してもかまいません。)
圧縮するフォルダー: C:\temp\ziptest
zipファイル: C:\temp\myzip.zip
フォルダーには何かファイルを最低1つは入れて置いてください。処理に時間がかかるのを避けるために大きなサイズのファイルは配置しないほうがよいです。
このメソッドのリファレンスはここです。
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.compression.zipfile.createfromdirectory
解答例と解説を見るには、下にスクロールしてください。
↓ もうちょっと下です。
System.IO.Compression.ZipFile.CreateFromDirectory(@"C:\temp\ziptest", @"C:\temp\myzip.zip");
リファレンスを見ると、CreateFromDirectoryメソッドには3つのオーバーロードがあることがわかります。説明を読むと一番上のオーバーロードでやりたいことが可能ですし、一番シンプルで良さそうです。
一番上のオーバーロードをクリックすると、このオーバーロードの定義が表示され、static がついていることから静的メソッドであることがわかります。
静的メソッドなので、クラス名.メソッド名 の形、つまり、 ZipFile.CreateFromDirecotory の形で呼び出すことができるのですが、既定では長い名前の名前空間も付けて System.IO.Compression.ZipFile.CreateFromDirecotory とする必要があります。
ファイル名などパスを指定する場合、通常の文字列内では \ がエスケープシーケンスの機能になってしまうので " " の前に @ を付けた逐語的文字列を使って、 \ が通常の文字と解釈されるようにするのが楽です。
ColorDialogクラス (読み方:ColorDialog = カラーダイアログ)を使うとユーザーに色を選択させることができます。これを使ってユーザーが選択した色をWindows フォーム アプリのフォームの背景色に設定しましょう。
ユーザーに色を選択させるには ColorDialogクラスの ShowDialogメソッド (読み方:ShowDialog = ショウダイアログ)を使用します。このメソッドを呼び出すとユーザーが色を選択するかキャンセルするまでプログラムは次のように進みません。今回は、ユーザーはキャンセルしないで必ず何か色を選択するものとします。
ユーザーが選択した色を取得するには ColorDialogクラスの Color プロパティ (読み方:Color = カラー)を使用します。
フォームの背景色を設定するにはフォームの BackColorプロパティ (読み方:BackColor = バックカラー)を使用します。
フォームのプログラムではキーワード this を使ってフォームのインスタンスにアクセスできます。
これだけ情報があれば、リファレンスを見なくてもできそうです
リファレンス
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.colordialog
解答例と解説を見るには、下にスクロールしてください。
↓ もうちょっと下です。
var dialog = new ColorDialog();
dialog.ShowDialog();
this.BackColor = dialog.Color;
ShowDialogメソッドは、非静的メンバーなので呼び出すにはnewを使ってColorDialogクラスのインスタンスを作成する必要があります。
ColorDialogクラスの名前空間は System.Windows.Forms です。Windows フォーム アプリでは省略可能です。
ColorDialogクラスのコンストラクターには引数がないので簡単にインスタンスを作成できます。
同じくShowDialogメソッドも引数はないので簡単に呼び出せます。
この問題は1個1個のメソッド・プロパティの使い方は簡単ですが、組み合わせて使えるかというところがポイントです。
最後の問題です。ちょっと難しいかもしれません。情報を読みこなす能力が求められると思います。
DirectoryInfoクラスのEnumerateFilesメソッド(読み方:DirectoryInfo = ディレクトリーインフォ、EnumerateFiles = イニューマレイトファイルズ)は、フォルダーの中からファイルを検索するメソッドです。
このメソッドを使って、マイピクチャーフォルダーの中に入っている拡張子が png であるファイルの数を数える下記のプログラムを完成させてください。子フォルダーがあればそれも対象にしてください。
//マイピクチャーフォルダーのパスを取得します。たとえば、C:\Users\rucio\Pictures です。
string myPictureFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
//子フォルダーも含め拡張子がpngのファイルをすべて取得します。
//★この部分にプログラムを追加して機能を完成させてください。
//結果を表示します。
MessageBox.Show($"{result.Count()}個見つけました!");
EnumerateFilesメソッドにはいくかオーバーロードがあります。この問題では第1引数が string型のsearchPattern, 第2引数が SearchOption型の searchOption である のオーバーロードを使用してください。
searchPattern引数に "*.png" を指定すると、「拡張子が png のファイル」という意味になります。
EnumerateFilesメソッドの戻り値の Count メソッドを呼び出すと、数を取得ることができます。
EnumerateFilesメソッドの戻り値は初級講座まだ説明していない「配列」というものなのですが、型推論で戻り値を受け取れば気になることはないでしょう。
リファレンス
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.directoryinfo.enumeratefiles
解答例と解説を見るには、下にスクロールしてください。
↓ もうちょっと下です。
//マイピクチャーフォルダーのパスを取得します。たとえば、C:\Users\rucio\Pictures です。
string myPictureFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
//子フォルダーも含め拡張子がpngのファイルをすべて取得します。
var info = new DirectoryInfo(myPictureFolderPath);
var result = info.EnumerateFiles("*.png", SearchOption.AllDirectories);
//結果を表示します。
MessageBox.Show($"{result.Count()}個見つけました!");
EnumerateFilesメソッドは非静的メソッドのため呼び出すにはインスタンスが必要です。
インスタンスを作成するにはコンストラクターを使用します。コンストラクターを呼び出すには new を使用します。
DirectoryInfoクラスのコンストラクターはフォルダー名を引数に取りますので、マイピクチャーフォルダーのパスを格納する変数 myPictureFolderPath を引数に渡します。
EnumerateFilesメソッドにはいくつかのオーバーロードがあります。どのオーバーロードを使うかは問題文で指定しています。.NET 6.0 では 4番目にヒントが表示されるオーバーロードがこれに該当します。
第1引数 searchPatternには、問題文に書いてあるように "*.png" を指定します。これで、拡張子がpngのファイルを検索できます。
第2引数の searchOption では子フォルダーを検索対象に含めるかどうかを指定できます。
第2引数の型SearchOptionは列挙型です。
第1引数の後ろのカンマを入力して、スペースを押すと入力候補が表示されます。
この中にSearchOption.から始まるものが2つ含まれており、構文上どちらかを指定すべきであることがわかります。
今回は子フォルダーも含めたいので、英語の意味が分かれば SearchOption.AllDirectories が正解ということがわかります。
TopDirectoryOnlyの意味は「トップのディレクトリーのみ」、AllDirectoriesの意味は「すべてのディレクトリー」です。
英語の意味が分からなかったり、ちゃんと調べたい場合は、リファレンスの出番です。
リファレンスには第2引数の SearchOption 型のところがリンクになって、この意味をさらに解説しているページにジャンプできます。
リンク先にはこのような説明があります。
この説明もちょっとわかりやすくはありませんが、不正確なことを書かないように表現するとこういう固い表現になります。
対象がWindowsだけではないので、「フォルダー」ではなく、「ディレクトリ」と表現します。「サブディレクトリ」は「子フォルダー」という意味です。「マウントされたドライブや…」以降は特に意味が分かりにくいですね。Windowsのファイルでいうところのショートカットのようなものの扱いが記載されています。「マウントされたドライブ」とはドライブ自体をショートカットのようにフォルダーの中に入れる技術です。シンボリックリンクはショートカットに似ていますが、本物のフォルダーのように扱うことができる機能などがあります。普段使いませんがWindowsでも使えます。このようにプログラムしていると、プログラム自体とは直接関係がない周辺の知識がないとよくわからないということがしばしばあります。
今回の練習問題の意図は、フレームワークの機能の呼び出し方がわかっているかの確認です。
フレームワークの機能は数千、数万とありますから、基本的な呼び出し方のルールを覚えて、それを未知の機能にあてははめていく能力が必要になります。
この練習問題をやってみて、全然正解できなくても解説を読んで理解できれば問題ないと思います。
解説を読んでもよくわからないようであれば、ちょっと問題があるかもしれません。初級講座の第6回 クラスの使い方 あたりから振り返ってみると良いかもしれません。ただ、あまりこだわりすぎて立ち止まるのも良くないので、完全に理解するまで立ち止まるのではなく、さらっと見返すくらいで、先に進んで良いと思います。
そもそも私の説明の仕方や出題が悪いと感じる方は掲示板で教えてください。
次の回では、日付と時刻について学びます。