実行中のプロセスの .NET のバージョンを取得する方法です。.NET Core 以降と .NET Framework では異なる点があり、.NET Framework では注意が必要です。
カテゴリ : C#
Windows 上の .NET 5 以降での破壊的変更です。文字列のソート、順序比較のデフォルトの動作が変更されました。パフォーマンスにも影響します。
実行環境に依存せず、一番良いパフォーマンスにする設定方法について記載します。
Generic の型引数 T の Type が参照型かどうかを判定する方法です。参照型(を含む)の場合は、参照を解放する場面に使用する想定です。
例えば、ArralPool に返す前の参照クリア、Remove した際の参照クリア のような場面です。
csproj で別プロジェクトを参照して、ビルドのみ実行するように依存関係を設定する方法です。
ビルドのみ実行するため、別プロジェクトのクラスを使用できませんし、ファイルもビルド出力しません。
通常はソリューションで設定することが多いと思いますが、sln を使用せずに設定します。
一般的には List<T>
を使用して要素を追加して行き、最後に ToArray()
することで配列を作成します。
この方法では、最後の配列以外に作業用のヒープメモリ確保が発生してしまいます。
プールと構造体を使用することで、最後の完成した配列に対して1回のみメモリ確保する実装例です。
新しい SDK 形式の csproj で .NET Framework 4.8 を対象にしているプロジェクトで、RuntimeIdentifiers に関するビルドエラーが発生しました。その対処方法を記載します。
通常は is や as でキャストできるか判定しますが、Type 指定でクラスやインターフェイスにキャスト可能か判定する方法です。
is と同じ結果になる方法だと思います。指定したクラスの派生または、指定したインターフェイスを実装しているか判定できます。
DateTime
には Kind
プロパティがあり、Utc
や Local
という状態を持つ場合があります。
基本的には Unspecified
であり、Ticks
の日時のみが処理されます。
しかし一部の処理では Kind
を意識する必要があるため、変換方法や注意点をまとめます。
.NET SDK 8 Preview 4 以降、AssemblyInformationalVersion の末尾に Git SHA が自動付与されるようになりました。
これは SDK の仕様なので、.NET Framework を対象とするプロジェクトにも影響します。この自動付与を無効に設定する方法を説明します。
Task.Run()
とラムダ式を使用すると、簡単にタスクを実行できます。しかし、ラムダ式で外部変数をキャプチャすると、クロージャによりメモリアロケーションが発生します。
外部変数を引数に取る静的メソッドを用意することで、ラムダ式のメモリアロケーションを削減できます。Task.Run()
では実現できないため、Task.Factory.StartNew()
を使用して実現する方法です。
.NET Standard や .NET Framework 開発環境においても、最新の C# 機能、.NET API を使用するための方法です。
\\
から始まる UNC パス のファイルをオープンする際に、例外が出るケースの対応方法です。
ビルドすると、SQLite.Interop.dll
がコピーされます。
公開(publish)した場合はコピーされないため、コピーされるように設定する方法です。
管理者権限でプロセスを実行する方法です。また反対に、管理者権限で実行中のプロセスから一般権限で別のプロセスを実行する方法です。
C# のプロジェクトを自己完結型で発行した場合や、NuGet のライブラリを使用した際に、サテライトアセンブリの言語フォルダが出力されます。
必要な言語フォルダのみ出力するように設定する方法です。
TCP, UDP の使用中のポートを全て取得する方法です。
アプリから動的に Web サーバーを立ち上げる際に、空きポートを指定する必要があったため、指定したポート番号以降の最初の空きポートを取得方法もメモします。
開いている NamedPipe の名前を全て取得する方法です。
.NET Core と .NET Framework の違いで例外が発生する注意点があります。
Environment.UserName ではなく、姓名のフルネームを取得する方法です。
Win32 API の GetUserNameEx
を使用して、高速に取得します。
Windows エクスプローラーのファイル順と同じように、文字列中の数字を値の大きさでソートします。OS に依存しない実装も対応します。
System.__ComObject
のインスタンスから COM インターフェイスの型名を取得する方法です。
await using
で DisposeAsync()
を確実に実行できますが、DisposeAsync().ConfigureAwait(false)
を使用したい場合は工夫が必要です。
struct においては IAsyncDisposable
へのキャストによるボクシングを回避して実行する方法を考えます。
公式ページ を見ると Webhook を使用して 1対1 自動応答をする Bot の作成を前提にしているように見えます。
Webhook なしで WebServer を用意せず、任意のグループチャットに対しても Messenger の自動化がしたいので調査しました。
早6年前、neue大先生の記事で得た知見ですが、.NET 7 Preview 1 でコンパイル後の結果が違うことに偶然気付いたので確認しました。
外部アセンブリからアクセスできる型かどうかの public
判定は Type.IsVisibleで可能で、Assembly.GetExportedTypes() で全てのパブリック型を取得できる。
この internal
版の判定を行いたい。public
, internal
, protected internal
で入れ子になったネスト型も含めて、同一アセンブリ内でアクセスできるかどうかを判定する。
ここでは protected
による継承でアクセスできるかどうかは判定対象外とする。