starzware

ITスキル

C#

.NET APIブラウザー NuGet NPOI CloseXML dotnetコマンド
TIPS
予約語
abstract as base bool break
byte case catch char checked
class const continue decimal default
delegate do double else enum
event explicit extern false finally
fixed float for foreach goto
if implicit in int interface
internal is lock long namespace
new null object operator out
override params private protected public
readonly ref return sbyte sealed
short sizeof stackalloc static string
struct swtich this throw true
try typeof uint ulong unchecked
unsafe ushort using virtual void
volatile while

// 10進数ベース 精度:28~29桁固定
bigdecimal
[システム]戻り値を指定して終了

//戻り値に0を設定して終了する
System.Environment.Exit(0);
[システム]コンソールに出力

//コンソール出力
Console.WriteLine("コンソールにメッセージを出力");
[システム]ソースブロック

#region ブロック
ソースブロック
#endregion
[ファイル]テキストファイル読み込み

using(var input = new TextReader(ファイル)){
  string line = string.Empty;
  while((line = input.ReadLine()) != null){
    //1行ごとの処理
  }
}//using
[ファイル]テキストファイル書き込み

using(var output = new TextWriter(ファイル, false)){
  output.Write("内容");
}//using
[ファイル](簡易)テキストファイルをすべて読み込む

string text = File.ReadAllText(@"C:¥Users¥xxxxx¥textfile.txt");
[ファイル](簡易)テキストファイルを配列にすべて読み込む

string[] lines = File.ReadAllLines(@"C:¥Users¥xxxxx¥textfile.txt");
[文字列]いろいろ

//数値を文字列に変換
int i = 10;
string s = i.ToString();
//指定文字で分割して配列にする
string s = "a,b,c";
string[] arr = s.Split(",");
//配列を結合
char[] arr = {'a','b','c'};
string s = string.Join("/", arr); //"a/b/c"
//
List list = new List<string>() {"aaa","bbb","ccc"};
string s = string.Join("/", list); //"aaa/bbb/ccc"
//空白除去
string s = "¥tabcdef¥r¥n";
string s1 = s.Trim(); //"abcdef"
string s2 = s.TrimStart(); //"abcdef¥r¥n"
string s3 = s.TrimEnd(); //"¥tabcdef"
string s4 = s.Trim('¥t','¥r','¥n'); //"abcdef"
string s5 = s.TrimStart('¥t'); //"abcdef¥r¥n"
string s6 = s.TrimEnd('¥r','¥n'); //"¥tabcdef"
//正規表現を使った文字の削除
using System.Text.RegularExpressions;
string s = "a1b2c3d4e5f";
string pattern = "[0-9]";
string s1 = Regex.Replace(s, pattern, ""); //"abcdef"
//一部を取得 開始,文字数
string s = "1234567";
string s1 = s.Substring(1,2); //"12"
//ゼロパディング
string s = "1234";
string s1 = s.ToString("D7"); // "0001234"
//指定文字を指定数繰り返して返す
char c = 'a';
string s1 = new string(c, 5); // "aaaaa"
//判定
string s = "abcde";
if(s.Contains("bcd")) //指定文字を含む場合
if(s.StartsWith("abc")) //指定文字で始まる場合
if(s.EndsWith("de")) //指定文字で終わる場合
if(s.Equals("abcde")) //一致している場合
if(string.IsNullOrEmpty(s)) //nullか空文字の場合
[ファイル]クラス
クラス 説明
BinaryReader バイナリファイルとして読み込み
BinaryWriter バイナリファイルとして書き込み
BufferedStream 他のStream(I/O)に対してバッファリングをする
Directory ディレクトリに関して静的メソッドを提供
DirectoryInfo ディレクトリ操作に関してインスタンスメソッドを提供
DirectoryNotFoundExceion ディレクトリなし例外
DriveInfo ドライブに関する情報を提供
DriveNotFoundExeption 使用できない/使用不可などによる例外
EndOfStreamException Streamの終端を超えての読み取りによる例外
EnumerationOptions ファイルとディレクトリのオプション(列挙型)
ErrorEventArgs Errorイベントの情報を提供
File 1つのファイルの操作のための静的メソッドを提供
FiileInfo ファイルの操作のためのインスタンスメソッドを提供
FileLoadExeption マネージドアセンブリが存在するが読み込みできない場合の例外
FileNotFoundException ファイルが存在しない場合の例外
FileStream ファイル用のStream(I/O)
FileStreamOptions FileStreamのオプション指定の列挙型
FileSystemAclExtensions アクセス制御リスト(ACL)のためのWindows固有の静的拡張メソッドを提供
FilieSystemEventArgs ディレクトリイベントにデータを提供
FileSystemInfo FileInfoとDirectoryInfoの基本クラス
FileSystemWatcher ファイルシステムの変更通知を受け取りイベント発生を待つ
InternalBufferOverflowException 内部バッファがオーバーフローした場合の例外
InvalidDataException データストリームが無効な形式である場合の例外
IOException IOエラーが発生した場合の例外
MemoryStream メモリを使用するStreamを作成
Path ファイルまたはDirectoryのパス情報Stringインスタンスで操作する
PathTooLongException パス名または完全修飾ファイル名が扱える文字数を超えた場合の例外
RandomAccess
RenamedEventArgs Renamedイベントのデータを提供
Stream (抽象クラス)
StreamReader 特定エンコーディングのTextReaderの実装(TextReaderが親クラス)
StreamWriter 特定エンコーディングのTextWriterの実装(TextWriterが親クラス)
StringReader 文字列から読み取るTextReaderの実装
StringWriter 文字列に書き込むTextWriterの実装
TextReader テキストファイル読み込みのためのStreamの実装
TextWriter テキストファイル書き込みのためのStreamの実装
UnmanagedMemoryAccessor メモリのアンマネージドブロックにマネージドコードからランダムアクセスできるようにする
UnmanagedMemoryStream マネージドコードからメモリのあンマネージドブロックにアクセスできるようにする
[ファイル/ディレクトリ]操作系

//フォルダ作成
Diretory.CreateDirectory(dir);
//フォルダ存在チェック
if(Diretory.Exists(dir)){
  //フォルダが存在する場合
}
//フォルダを取得
string dir = Path.GetDirectoryName(filefullpath);
//指定フォルダの配下のフォルダ群を取得
foreach(var thisFolder in Directory.GetDirectories(dir)){
  //配下フォルダごとの処理
}
//指定フォルダの配下のファイル群を取得
foreach(var thisFile in Directory.GetFiles(dir)){
  //配下ファイルごとの処理
}
//拡張子を取得
var ext = Path.GetExtension(thisFile);
//ファイル名を取得
var filename = Path.GetFileName(thisFile);
//プラットフォームを意識したパスの構築
var filepath = Path.Combine("フォルダ1","フォルダ2", "ファイル");
dotnetコマンド
説明 コマンド
テンプレートの一覧を表示 dotnet new -h
ソリューションファイルの作成 dotnet new sln
(ディレクトリ名と同じファイル名になる)
ソリューションファイルにプロジェクトを追加 dotnet sln add [プロジェクトファイル]
[コンソール]アプリプロジェクトを作成 dotnet new console -n [プロジェクト名]
プロジェクト作成(WinForm) dotnet new winforms -n [プロジェクト名]
プロジェクト作成(avalonia) dotnet new avalonia.app -n [プロジェクト名]
[テスト(MSTest)]プロジェクトを作成 dotnet new mstest
[ASP.NET Core Web(MVC)]アプリプロジェクトを作成 dotnet new mvc
プロジェクト参照を追加(主にテストプロジェクトにテスト対象プロジェクトを追加する) dotnet add reference [プロジェクトファイル]
ビルド dotnet build
クリーン dotnet clean
実行 dotnet run
テスト(主にテストプロジェクト) dotnet test
リリース(Windows[64bit]) dotnet publish -c Release --self-contained true -r win-x64
リリース(Mac[64bit]) dotnet publish -c Release --self-contained true -r osx-x64
リリース(Linux[64bit]) dotnet publish -c Release --self-contained true -r linux-x64
ClosedXML(Excel操作ライブラリ)を追加 dotnet add package ClosedXML
MailKit(メールライブラリ)を追加 dotnet add package mailkit
C#開発のためのVSCodeのプラグイン
プラグイン 説明
C# for Visual Stdio Code インテリセンスなどの一通りの機能を提供
VS Sharper for C# namespaceやclass、interfaceなどの情報を自動で入力してくれる
Auto-Using for C# usingを自動で解決してくれる
.NET Core Test Explorer テストプロジェクトの実行・管理をする
NuGet Package Manager NuGetパッケージの検索・インストールができるようになる
C# FixFormat ソースコードにインデントやスペースを入れる(Shfit + Alt + F)
C#開発のためのVSCodeのショートカットキー
F5 実行
F10 ステップオーバー
F11 ステップイン
Shift+F11 ステップアウト
F12 定義へ移動
Alt+F12 定義を参照
Ctrl+Shift+U 標準出力パネルの表示/非表示
Ctrl+Shift+E エクスプローラビューの表示
Ctrl+Shift+D デバッグビューの表示
Ctrl+Shfit+¥ 対応する括弧にジャンプ
Ctrl+Shfit+[ コードフォルディング(折りたたみ)
Ctrl+/ コメントアウト/アンコメント
[関数]GetTimestampString

string GetTimestampString(){
  return DateTime.Now.ToString("yyyyMMddHHmmss");
}
ファイル操作

// ファイルコピー
System.IO.File.Copy(@"C:¥test¥a.txt", @"C:¥test¥b.txt");
// ファイル移動
System.IO.File.Move(@"C:¥test¥a.txt", @"C:¥test¥b.txt");
// ファイル削除
System.IO.File.Delete(@"C:¥test¥c.txt");
// ファイル一覧
System.IO.Directories.GetFiles(@"C:¥test¥");
// ディレクトリ一覧
System.IO.Directories.GetDirectories(@"C:¥test¥");
[配列]結合

int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 4, 6 };
// LINQで連結する
int[] concatenatedArray = array1.Concat(array2).ToArray();
メール送信(SmtpClient)


// FROM
string senderMail = "sender@hogehoge.domain";
// TO
string recipientMail = "okurisaki@ageage.domain";
// 件名
string subject = "けんめい";
//本文
string body = "こんにちは。\r\n2行目\r\n3行目";

//SmtpClientオブジェクトを作成する
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();

//SMTPサーバーを指定する
client.Host = "localhost";
client.Port = 25;

//SMTPサーバーに送信する設定にする(既定はNetwork)
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;

//メール送信
client.Send(senderMail, recipientMail, subject, body);

//後始末(.NET Framework 4.0以降)
client.Dispose();
メール送信(古い)

// サーバ設定
System.Web.Mail.SmtpMail.SmtpServer = "mail.sample.desu.domain";

// メッセージ設定
System.Web.Mail.MailMessage message = new System.Web.Mail.MailMessage();
message.From = "system@sample.desu.domain";
message.To = "okurisaki1@sample.desu.domain; okurisaki2@sample.desu.domain";
message.Cc = "ccsaki1@sample.desu.domain; ccsaki@sample.desu.domain";
message.Subject = "プログラムから送信する電子メール";
message.BodyEncoding = System.Text.Encoding.UTF8;
message.BodyFormat = System.Web.Mail.MailFormat.Html;

message.Body = "この電子メールはプログラムから送信しています。\r\n"
             + "これは本文の2行目です\r\n";

// 添付ファイル
System.Web.Mail.MailAttachment attachment = new System.Web.Mail.MailAttachment(
    @"c:\attatchedsamplefile.dat",
    System.Web.Mail.MailEncoding.Base64);
message.Attachments.Add(attachment);

// メール送信
System.Web.Mail.SmtpMail.Send(message);
EXE起動

string exePath = @"C:\Tools\MyApp.exe";

// プロセスの設定
System.Diagnostics.ProcessStartInfo processInfo = new System.Diagnostics.ProcessStartInfo
{
  FileName = exePath, // 実行するEXE
  Arguments = "arg1 arg2", // 必要ならコマンドライン引数
  RedirectStandardOutput = true, // 標準出力を取得
  RedirectStandardError = true,  // エラー出力を取得
  UseShellExecute = false, // シェルを使用しない
  CreateNoWindow = true // コンソールウィンドウを表示しない
};

// プロセス実行
using (System.Diagnostics.Process process = new System.Diagnostics.Process { StartInfo = processInfo })
{
  // 実行して終了を待つ場合
  //   実行して終了を待たない場合は、Startメソッドだけ実行
  process.Start();
  string output = process.StandardOutput.ReadToEnd();
  string error = process.StandardError.ReadToEnd();
  process.WaitForExit();
}
ファイル名チェック/ディレクトリ名チェック


// ファイル名チェック 禁止文字はPath.GetInvalidFilenameCharsに定義されている
string filename = @"xxxxxx";
if (filename.IndexOfAny(Path.GetInvalidFilenameChars()) > 0)
{
  // エラー
}

// ディレクトリ名チェック 禁止文字はPath.GetInvalidPathnameCharsに定義されている
string dirname = @"xxxxxx";
if (dirname.IndexOfAny(Path.GetInvalidPathChars()) > 0)
{
  // エラー
}

ファイルが書き込めるかをチェック1

string filePath = "書き込み確認するファイルパス";
try
{
  using(FileStream fp = File.Open(filePath, File.Open, FileAccess.Write)){
    // 書き込める
  }
}
catch (Exception ex)
{
  // 書き込み不可
}
ファイルが書き込めるかをチェック2

string filePath = "書き込み確認するファイルパス";
try
{
  FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, filePath);
  permission.Demand(); // 権限がない場合は例外発生
  // 書き込める
}
catch
{
  // 書き込み不可
}
[log4net]App.configにlog4net設定をした場合の処理

// [.NET CLI]でのパッケージ追加 
// dotnet add package log4net
using System;
using System.IO;
using System.Reflection;
using log4net;
using log4net.Config;

class Program
{
  // クラスレベルでロガーを定義
  private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

  static void Main()
  {
    // log4net の設定を読み込む
    XmlConfigurator.Configure();

    log.Debug("デバッグメッセージ");
    log.Info("情報メッセージ");
    log.Warn("警告メッセージ");
    log.Error("エラーメッセージ");
    log.Fatal("致命的なエラーメッセージ");

    Console.WriteLine("ログ出力が完了しました。");
  }
}

文字列代入時の@と$

// @をつけると¥をそのまま書ける
string path = @"C:\Users\Public\Documents";
// $をつけると変数展開される
string name = "sato";
string hello = $"こんにちわ、{name}さん!"; // こんにちわ、satoさん!
// 両方
string user = "sato";
string path = @$"C:\Users\{user}\Documents"; // C:\Users\sato\Documents

[avalonia]MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="タイトル"
  Width="400"
  Height="200">

  <StackPanel Margin="10">
    <Button Content="ボタン名" Click="Read_Click"/>
    <TextBox Name="ResultBox" Margin="0,5,0,0"/>
  </StackPanel>
</Window>
ZIPファイル(ZipFile / ZipArchive)

// System.IO.Compression.ZipFile / ZipArchive

// 指定フォルダに丸ごと展開
ZipFile.ExtractToDirectory(
  zipPath: "input.zip",
  destinationDirectoryName: "output",
  overwriteFiles: true   // .NET 6+
);

// ZIPを作成する
ZipFile.CreateFromDirectory(
  sourceDirectoryName: "inputFolder",
  destinationArchiveFileName: "output.zip",
  CompressionLevel.Optimal,
  includeBaseDirectory: false
);

// ZIPの中身を確認する
using var zip = ZipFile.OpenRead("input.zip");
foreach (var entry in zip.Entries)
{
    Console.WriteLine($"{entry.FullName} ({entry.Length} bytes)");
}

// ZIPから特定ファイルだけ取り出す
using var zip = ZipFile.OpenRead("input.zip");
var entry = zip.GetEntry("index.html");
if (entry != null)
{
    entry.ExtractToFile("index.html", overwrite: true);
}

// ファイルを追加
using var zip = ZipFile.Open("archive.zip", ZipArchiveMode.Update);
zip.CreateEntryFromFile(
    sourceFileName: "add.txt",
    entryName: "docs/add.txt"
);

// ファイルを削除
using var zip = ZipFile.Open("archive.zip", ZipArchiveMode.Update);
var entry = zip.GetEntry("docs/old.txt");
entry?.Delete();

// メモリ上でZIPを扱う(Web / GUI向け)
using var ms = new MemoryStream();
using (var zip = new ZipArchive(ms, ZipArchiveMode.Create, true))
{
    var entry = zip.CreateEntry("test.txt");
    using var writer = new StreamWriter(entry.Open());
    writer.Write("hello");
}
byte[] zipBytes = ms.ToArray();

using var(C# 8+)

書き方	有効範囲	特徴
using (...) {}	ブロック内のみ	範囲が明確
using var x = ...;	スコープ末尾まで	ネスト減って読みやすい
--- Excelファイル(CloseXML)の例 ---
using var book = new XLWorkbook(path);
var sheet = book.Worksheets.First();
 ↓ 以下と同じ
var book = new XLWorkbook(path);
try
{
    var sheet = book.Worksheets.First();
}
finally
{
    book.Dispose();
}
=== 以下、例示のみ(比較なし) ==================================================
--- テキストファイル読み込み ---
using var reader = new StreamReader("sample.txt");
string text = reader.ReadToEnd();
Console.WriteLine(text);
--- テキストファイル書き込み ---
using var writer = new StreamWriter("out.txt");
writer.WriteLine("1行目");
writer.WriteLine("2行目");
--- バイナリファイル書き込み ---
using var reader = new StreamReader("input.txt");
using var writer = new StreamWriter("output.txt");
while (!reader.EndOfStream)
{
    writer.WriteLine(reader.ReadLine());
}
--- JSONファイル読み込み ---
using var fs = File.OpenRead("data.json");
using var reader = new StreamReader(fs);
string json = reader.ReadToEnd();
--- ZIPファイル ---
using var zip = ZipFile.OpenRead("sample.zip");
foreach (var entry in zip.Entries)
{
    Console.WriteLine(entry.FullName);
}
CloseXML


[ブック]
(新しいファイルを作る)
using var book = new XLWorkbook();
(既存ファイルを開く)
using var book = new XLWorkbook(path);

[シート]
(最初のシートを取得する)
var sheet = book.Worksheets.First();
(シート"Data"を取得する)
var sheet = book.Worksheet("Data");
(シート"Data"を追加する)
var sheet = book.AddWorksheet("Data");
(指定のシート"Data"があれば取得し、なければ作成する)
var sheet = book.Worksheets.Contains("Data")
  ? book.Worksheet("Data")
  : book.AddWorksheet("Data");

[セル]
-- 設定
sheet.Cell("A1").Value = "作成日時";
sheet.Cell("B1").Value = DateTime.Now;
-- 数式を設定する
sheet.Cell("C1").FormulaA1 = "=A1+B1";

-- スタイル
sheet.Cell("A1").Style
     .Font.SetBold()
     .Fill.SetBackgroundColor(XLColor.LightGray)
     .Border.OutsideBorder = XLBorderStyleValues.Thin;

-- セルの背景色を塗る
sheet.Cells().Style.Fill.BackgroundColor = XLColor.White;

-- セルを文字列にする
sheet.Range("A:A").Style.NumberFormat.Format = "@";

[メモ]
var cell = ws.Cell("A1");
(メモの有無)
if (cell.HasComment)
(メモを取得)
var comment = ws.Cell("A1").Comment;
(取得)
string text = comment.Text;
string author = comment.Author;
(編集)
comment.AddText("これはメモです");
comment.Author = "System";
(削除)
comment.Delete();
(表示)
comment.Visible = true;  // 常に表示
comment.Visible = false; // マウスオーバー
(大きさ)
comment.Width = 200;
comment.Height = 100;