LoginSignup
9

posted at

updated at

C# - よく使う機能の逆引きリファレンスを目指して

Formに配置できるコントロールは「こちら」

1. ファイル関連

1-1. ファイルの読み書き

1-1-1. 楽な方法(一括処理)

やりたいこと コード 記事or外部リンク 補足・注意事項
指定したテキストファイルからデータを一括で読み込む(改行を区切りとして配列に分割した形で取得) File.ReadAllLines dobon.net 文字コードに注意
指定したテキストファイルからデータを一括で読み込む File.ReadAllText dobon.net 文字コードに注意
指定したバイナリファイルからデータを一括で読み込む1 File.ReadAllBytes dobon.net
指定したテキストファイルへデータを一括で書き込む(文字列配列を渡す。改行が付加される。) File.WriteAllLines 文字コードに注意
指定したテキストファイルへデータを一括で書き込む File.WriteAllText 文字コードに注意
指定したバイナリファイルへデータを一括で書き込む File.WriteAllBytes dobon.net

補足. 使い分けについて

巨大なファイルを開くときはメモリや処理時間などリソースを大量に使用するので 1-1-2 章の方法を使う必要あり。

補足. エンコードの指定について

エンコードを指定するにはEncodingクラスを使う。
標準ライブラリのものは指定しないとUTF-8が使われるものがほとんど(例外はあるかも)。(ASCII文字しか含まない場合は、UTF-8でもShift_JISでもよい。)
Shift_JISを指定するにはEncoding.GetEncoding("shift_jis")を使う。

1-1-2. 細かく制御する方法

主なクラス

やりたいこと 使用するクラス 記事or外部リンク 補足・注意事項
文字列データを読み込む StreamReaderクラス Samurai Blog 文字コードに注意
文字列データを書き込む StreamWriterクラス 文字コードに注意
ファイルに対してデータを読み書きする FileStreamクラス dobon

なお、ファイルを開くときはusing構文を使いましょう。

1-1-2-1. StreamReader関連

やりたいこと コード 記事or外部リンク 補足・注意事項
■ファイルを開く
文字コードを指定してテキストファイルを開く new StreamReader(ファイルパス,エンコード)
■開いたファイルに対して操作する
開いているファイルから1行読み込む ReadLine すでに終端に達している場合はnullが返る

1-1-2-2. StreamWriter関連

やりたいこと コード 記事or外部リンク 補足・注意事項
■ファイルを開く
文字コードを指定してテキストファイルを開く new StreamWriter(ファイルパス,エンコード)
■開いたファイルに対して操作する
文字列を書き込む Write

WriteLineは無いようです。
改行コードについては下記が参考になりそう。

1-1-2-3. FileStream関連

やりたいこと コード 記事or外部リンク 補足・注意事項
■ファイルを開く
指定したファイルからデータを読み込む File.OpenRead new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)と同じ
指定したファイルへデータを書き込む File.OpenWrite new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)と同じ
指定したファイルを作成して書き込む File.Create new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None)と同じ。ファイルが存在する場合は上書きされる。
■開いたファイルに対して操作する
指定したバイト位置に移動する Position, Seek
指定byte数だけ読み出す Read(byte配列,オフセットindex,byte数) 読み出せたbyte数が返る
指定byte数だけ書き込む Write(byte配列,オフセットindex,byte数)

1-2. ファイル名・パスを選ぶ

やりたいこと コード 記事or外部リンク 補足・注意事項
(読み込む対象の)ファイルを選択するダイアログを開く OpenFileDialog dobon.net [STAThread]Mainメソッドの真上の行に入れること!
(保存先の)ファイルを選択するダイアログを開く SaveFileDialog dobon.net [STAThread]Mainメソッドの真上の行に入れること!
フォルダを選択するダイアログを開く FolderBrowserDialog dobon.net [STAThread]Mainメソッドの真上の行に入れること!
Drag&Dropでファイルを指定する(ファイルのパスを受け取る) - dobon.net [STAThread]Mainメソッドの真上の行に入れること!
指定フォルダからファイルを検索する Directory.GetFiles dobon.net SearchOption.AllDirectoriesを指定するとサブフォルダ以下を含めて検索する
指定フォルダからフォルダを検索する Directory.GetDirectories
指定フォルダからファイルとフォルダを検索する Directory.GetFileSystemEntries
カレントディレクトリを取得する Environment.CurrentDirectory Directory.GetCurrentDirectory() でも同様
実行しているパスを取得する Assembly.GetExecutingAssembly().Location ファイル名を含む。1-3章の下部のコード例参照

1-3. ファイル名・パスに対する操作

Pathクラスで色々やれる。

やりたいこと コード 記事or外部リンク 補足・注意事項
フルパスを取得する Path.GetFullPath
親となるフォルダのパスを取得する Path.GetDirectoryName 振る舞いを本表の直下に記載。詳細は左記リンク先のサンプルを参照
ファイル名(拡張子を含む)を取り出す Path.GetFileName
ファイル名(拡張子を除く)を取り出す Path.GetFileNameWithoutExtension
拡張子だけ取り出す Path.GetExtension 結果はドット"."を含む。
拡張子がない場合は空文字("")が結果となる。
フォルダ名を連結する Path.Combine

以下、GetDirectoryNameの振る舞い。


Path.GetDirectoryName(@"C:\MyDir\MySubDir\myfile.ext"); // returns 'C:\MyDir\MySubDir'
Path.GetDirectoryName(@"C:\MyDir\MySubDir");            // returns 'C:\MyDir'
Path.GetDirectoryName(@"C:\MyDir\");   // returns 'C:\MyDir'
Path.GetDirectoryName(@"C:\MyDir");    // returns 'C:\'
Path.GetDirectoryName(@"C:\"); // returns ''

実行パスの取得など

// using System; // to use Console class
// using System.IO; // to use Path class
// using System.Reflection; // to use Assembly class
string execPath = Assembly.GetExecutingAssembly().Location;
string execDirectory = Path.GetDirectoryName(execPath);
string settingFilePath1 = Path.Combine(execDirectory, @"hoge.txt");
string settingFilePath2 = Path.Combine(execDirectory, @"foo\hoge.txt");
string settingFilePath3 = Path.Combine(execDirectory, @"..\hoge.txt");
string settingFilePath4 = Path.GetFullPath(settingFilePath3);
Console.WriteLine(execPath);         // C:\MyDir\GetExecPath.exe
Console.WriteLine(execDirectory);    // C:\MyDir
Console.WriteLine(settingFilePath1); // C:\MyDir\hoge.txt
Console.WriteLine(settingFilePath2); // C:\MyDir\foo\hoge.txt
Console.WriteLine(settingFilePath3); // C:\MyDir\..\hoge.txt
Console.WriteLine(settingFilePath4); // C:\hoge.txt

1-4. ファイルやフォルダの有無や属性を調べる

やりたいこと コード 記事or外部リンク 補足・注意事項
ファイルが存在するか調べる File.Exists FileInfoクラスを使う方法もある
フォルダが存在するか調べる Directory.Exists
ファイルの属性を調べる File.GetAttributes
ファイルの最終更新日時を調べる File.GetLastWriteTime
ファイルのサイズを調べる FileInfo.Length Samurai Blog

1-5. ファイルやフォルダの移動・コピー・削除

やりたいこと コード 記事or外部リンク 補足・注意事項
ファイルを移動する File.Move
ファイルをコピーする File.Copy
ファイルを削除する File.Delete
フォルダを作成する Directory.CreateDirectory
フォルダを削除する Directory.Delete

1-6. 設定ファイルの読み書き

やりたいこと コード 記事or外部リンク 補足・注意事項
オブジェクトをXMLファイルへ保存する・読み込む System.Xml.Serialization.XmlSerializer dobon.net

1-7. XMLファイルを読み込む

やりたいこと コード 記事or外部リンク 補足・注意事項
XMLファイルを読み込む XElement.Load 侍エンジニアブログ
子要素を取得する Elements()
要素名を取得する Name
属性を取得する Attribute(XName)
属性を全て取得する Attributes()
値(タグで囲まれたテキスト)を取得する Value

1-8. zipファイルを扱う

やりたいこと コード 記事or外部リンク 補足・注意事項
zipファイルを作成する ZipArchive C# - VisualStudioもライブラリも使わずにZipファイルを生成する - Qiita コンパイル時にパスを通す必要あり(左記記事参照)

2. 文字列関連

String型の重要な特性について ⇒ String型におけるよくある勘違い - dobon.net

Stringクラスのプロパティやメソッドには、データの内容を変更できるものがありません。その代わりに、新しいデータが作成されます。

以下 2-3. に例を記載しています。

2-1. 数値と文字列の間の変換

参考:【C#入門】文字列を数値に、数値を文字列に変換する方法 | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
など

やりたいこと コード 記事or外部リンク 補足・注意事項
数値を文字列に変換する .ToString()
※リンク先はintのもの
数値を16進文字列に変換する .ToString("X4")
※リンク先はintのもの
桁数を指定できる。(0埋め)
文字列を数値に変換する Convert.ToInt32()
Convert.ToInt64()など
16進文字列を数値に変換する Convert.ToInt32(文字列,16)など 16進の場合は、先頭の0xを許容する。16進以外は、2, 8, 10進が指定可能。
パディングする(桁数をそろえる) String.PadLeft 数値変換専用ではないが、数値変換と合わせて使うケースが多そうなのでここに記載してみた。

2-2. 文字列を調べる(一致性の判定)

基本的に、大文字小文字を区別します。引数にStringComparisonがあるメソッドの場合は StringComparison.InvariantCultureIgnoreCase などを指定すれば、大文字小文字を区別しないようにできます。

やりたいこと コード 記事or外部リンク 補足・注意事項
文字数を調べる Length 2
特定の文字列と同一内容の文字列かを調べる 文字列 == 文字列 3
なお、中身の完全一致をチェックするので、大文字小文字を区別します。区別したくない場合はCompareCompareToなどを使います。
特定の文字列で始まっているかを調べる StartsWith
特定の文字列で終わっているかを調べる EndsWith
特定の文字列を含んでいるかを調べる Contains 大文字小文字を区別します
文字列の出現位置を調べる IndexOf
文字列の出現位置を末尾から調べる LastIndexOf

2-3. 文字列処理(加工処理)

加工結果は代入しましょう。
例: s.Trim()sを変更するのではなく、新しく文字列を生成して返します。

string s = "  hoge";

// NG例
s.Trim();             // Trim()した結果を代入していない(結果を捨てている)
Console.WriteLine(s); // "  hoge"

// OK例
string t = s.Trim();
Console.WriteLine(t); // "hoge"
やりたいこと コード 記事or外部リンク 補足・注意事項
先頭と末尾の空白を削除する Trim 空白の代わりに削除対象文字を指定することも可能
先頭の空白を削除する TrimStart 空白の代わりに削除対象文字を指定することも可能
末尾の空白を削除する TrimEnd 空白の代わりに削除対象文字を指定することも可能
小文字に変換する ToLowerInvariant 4
大文字に変換する ToUpperInvariant 4
文字列を区切り文字(列)で分割する Split(区切り) 第一引数は配列なので new char[]{','} とか new string[]{","} を指定する
固定文字数ごとに分割する 単体で実現できる機能が無い Toraja - qiita
文字列の配列を結合する String.Join(区切り, 配列) dobon.net 第一引数は文字。(charではなくstring)
部分文字列を得る Substring(開始位置,文字数) 開始位置のみを指定する(引数が1つのメソッド)の場合、開始位置から末尾までを取得
置換対象文字(列)を全て置換する Replace(置換対象,置換後)

2-4. 正規表現

やりたいこと コード 記事or外部リンク 補足・注意事項
特定のパターン(正規表現)にマッチしているかを調べる RegexMatch
特定のパターン(正規表現)にマッチした部分を取り出す RegexMatch 本章内参照
置換する Regex.Replace(文字列,正規表現,マッチ部置換用文字列) など @IT staticメソッドとそうでないメソッドが同名(Replace)で混在している
置換対象に処理をして置換する .Replace(文字列,(m)=>{}) 本章内参照 (m)=>{}MatchEvaluatorで、Matchを受け取ってstringを返す

特定のパターン(正規表現)にマッチした部分を取り出す

Regex r = new Regex(@"^#define +([_A-Za-z][_A-Za-z0-9]*) +(0x[0-9A-Fa-f]+)$");
Match m = r.Match(s); // sは対象文字列
if ( m.Success ) {
    Console.WriteLine(m.Groups[1].Value); // ([_A-Za-z][_A-Za-z0-9]*) の部分にマッチした文字列
    Console.WriteLine(m.Groups[2].Value); // (0x[0-9A-Fa-f]+) の部分にマッチした文字列
}

置換対象に処理をして置換する

// 16進文字列を2桁ずつに切り分けて`,`区切りで10進数に変換する例
string s = "abcdef";
Regex r = new Regex(@"([0-9A-Fa-f]{2})");
Console.WriteLine(r.Replace(s,(m)=>{return Convert.ToInt32(m.ToString(),16)+",";}));
// 171,205,239,

2-5. サロゲートペアをケアする

サロゲートペア - Google検索

主にStringInfoクラスを使う。

やりたいこと コード 記事or外部リンク 補足・注意事項
文字数を取得する LengthInTextElements
i番目の文字を取得する StringInfo.GetNextTextElement(対象文字列,i)
i番目の文字からn文字分の文字列を取得する SubstringByTextElements(i,n)
(stringにおける各charの)インデックスの配列を得る StringInfo.ParseCombiningCharacters
文字に分解して順に処理する GetTextElementEnumerator koara-local - Qiita
文字からUnicodeコードポイントを取得する Char.ConvertToUtf32
サロゲートペアか判定する Char.IsHighSurrogate, Char.IsLowSurrogate, Char.IsSurrogatePair

2-6. 文字コード変換

2-6-1. ASCIIコード値と文字の変換

やりたいこと コード 記事or外部リンク 補足・注意事項
ASCIIコード(0x41) → 文字('A') 数値を(char)でキャスト @IT
文字('A') → ASCIIコード(0x41) 文字を(int)等でキャスト @IT

charはUTF-16なので、実際はASCIIではなくUTF-16との変換をしている。

2-6-2. 文字列⇔バイト配列

やりたいこと コード 記事or外部リンク 補足・注意事項
文字列→byte配列 エンコード.GetBytes(文字列) dobon
byte配列→文字列 エンコード.GetString(byte配列) dobon, C#ちょこっとリファレンス

2-6-3. 文字コードの判別

自動判別する機能は標準では用意されていない。

2-7. StringBuilder

大きなデータを扱ったり、繰り返し処理が膨大な場合など、処理効率が気になるシーンでは、文字列のメモリバッファを書き換え可能なStringBuilderを使う。

3. データ構造

配列、List、Dictionaryの宣言方法と初期値付きの初期化方法

3-1. 配列

やりたいこと コード 記事or外部リンク 補足・注意事項
要素数を取得する Length
要素をコピーする Array.Copy(コピー元,コピー先,要素数)
要素をコピーする Array.Copy(コピー元,コピー元offset,コピー先,コピー先offset,要素数)
要素を検索する Array.IndexOf 末尾から検索する場合はLastIndexOfを使う
配列のコピーを作成する Clone() as 型名[] 要素が参照型の場合は要注意シャローコピーとディープコピー(C#) - 超初心者向けプログラミング入門
リサイズする(要素数を変更する) Array.Resize refについての説明: 参照渡し - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
ソートする(規則に従って並び替える) Array.Sort dobon.net

C#では多次元配列も使用できます。

3-2. List<>

要素数が事前に確定しないようなシーンで、配列の代わりに使うことが多い。

やりたいこと コード 記事or外部リンク 補足・注意事項
要素数を取得する Count 配列の場合は.LengthだけどListはこれ。
要素を末尾に追加する Add(要素)
要素を指定位置に追加する Insert(インデックス,要素)
要素を削除する RemoveAt(インデックス) foreachの中などで自身の要素を削除すると不整合を引き起こし得る
要素を削除する(最初に見つかった要素のみ) Remove(要素) foreachの中などで自身の要素を削除すると不整合を引き起こし得る
一致する要素を全て削除する RemoveAll(要素) foreachの中などで自身の要素を削除すると不整合を引き起こし得る
要素が含まれているか調べる Contains(要素)
配列に変換する ToArray()

3-3. Dictionary<キーの型,値の型>

やりたいこと コード 記事or外部リンク 補足・注意事項
要素を追加する Add(キー,値) キーが登録済みの場合は例外が発生する
要素の値にアクセスする [キー] キーが未登録の場合は例外が発生する(代入先(=setアクセス)の場合は例外は発生せず、要素が追加される)
要素を削除する Remove(キー)
キーが登録済みか調べる ContainsKey(キー)
  • キーnullは使用できない
  • foreach文で取り出せる要素の型は、KeyValuePair

3-4. その他

データ構造 コード 記事or外部リンク
スタック Stack<> C# スタックの基本的な使い方(データの取り出し、格納、読み込みなど) - ミドリ黄のプログラミングメモノート
キュー Queue<> 【C#】QueueとConcurrentQueueの使い方 - PG日誌
自動ソートList SortedList<,> C# の SortedList の使い方 - 解析エンジニアの自動化 blog3
自動ソートDictionary SortedDictionary<,> 【C#】Dictionaryは1種類だけじゃない!SortedとOrderedを用途に応じて使い分けよう!

ツリー構造に関しては、GUI向けのものしか標準にはないっぽい。。(TreeViewTreeNode)

4. 日時情報関連

DateTime構造体

4-1. 取得

やりたいこと コード 記事or外部リンク 補足・注意事項
現在の日時を取得する DateTime.Now 呼ぶたびに当然結果が変わるので、使い方に注意
現在の日付を取得する DateTime.Today Nowの時間部分を00:00:00としたもの

4-2. 情報の分解

やりたいこと コード 記事or外部リンク 補足・注意事項
年を取り出す .Year 左記Microsoftのドキュメントによると1~9999。0が無い!?
.Month 1~12
.Day 1~31
日(1年のうちの) .DayOfYear 1~366
曜日 .DayOfYear DayOfWeek型として返る
.Hour 0~23
.Minute 0~59
.Second 0~59
ミリ秒 .Millisecond 0~999
Ticks .Ticks

4-3. フォーマット変換

例:
DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")

年号に関しての注意

国によって年月日の表記順の常識が異なるので注意

4-4. 時差の考慮(UTCと現地時間)

やりたいこと コード 記事or外部リンク 補足・注意事項
現在の日時を取得する(UTC) DateTime.UtcNow 呼ぶたびに当然結果が変わるので、使い方に注意
LocalTime→UTC .ToUniversalTime()
UTC→LocalTime .ToLocalTime()
UTCか現地時間かを判別する .Kind DateTimeKind型として返る

5. 画像関連

BitmapImageGraphics

画像、印刷(GDI+) - .NET Tips (VB.NET,C#...)

5-1. 画像をピクセル単位で処理する

6. 外部プログラムを実行する

6.1. exe

6.2. DLL (Windows APIもここに含む)

6.2.1. C#以外で作られたDLLを呼び出す

DllImport属性

6.2.2. C#で作られたDLLを呼び出す

7. クリップボードの取得と設定

未整理

[STAThread]つける必要あり。

リトライあり

// using System.Windows.Forms;
// GUIじゃなくても使用可能
string s = "xxx";
try { Clipboard.SetText(s); }
catch ( System.Runtime.InteropServices.ExternalException ) { // クリアに失敗
    // 1回だけリトライする
    try { Clipboard.SetText(s); }
    catch ( System.Runtime.InteropServices.ExternalException e2 ) { Console.WriteLine(e2); }
}

8. 数値計算

2進浮動小数点数 double
10進浮動小数点数 decimal
複素数Complex
多倍長整数 BigInteger

※:csc.exeでコンパイルする場合は、csc.exeの引数に/r:System.Numerics.dllを指定必要。

8-1. 乱数生成

8-2. 数学関数

高校数学レベルの関数は大体 Math classにある。円周率とネイピア数も。

9. その他(例外処理やデバッグお役立ち系)

この章ではとくに、言語仕様によるものと標準クラスの機能をごちゃ混ぜで書いているので、しっかり理解したい場合は言語仕様を解説しているサイトを見るのをお勧めします。

9.1. 例外を処理する

例外発生をとらえるには try{...}catch(){...}finally{...}構文を使う。

9.1.1. オーバーフローの検出を切り替える

checked{}, unchecked{} ブロック

9.2. コンソールに出力する

Console.WriteLine()
Console.Error.WriteLine()

(章立てが適切ではないので気が向いたら見直す・・)

9.3. 処理時間を測る

参考サイト

  1. ファイルがテキストだろうがバイナリだろうが関係なく、byte配列としてファイル内容を読み込む。

  2. サロゲートペアとか結合文字とか、見た目1文字だけど内部表現が2文字以上になるやつが世の中には存在するので注意。

  3. String型は参照型の中では特殊な扱いになっていて、C#においてはString同士を==を使って比較すると中身の比較がなされる。

  4. String.ToUpper/ToUpperInvariantとToLower/ToLowerInvariantメソッドで異なる結果となる例 (C#) - .NET サンプルコード - 総武ソフトウェア推進所 2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
9