20200917のC#に関する記事は2件です。

ASP.NET Core における Razor(*.cshtml) ファイルの実行時コンパイル

ASP.NET Core での Razor ファイルのコンパイル

ASP.NET Core では、Web ページ(.csthml) の実行時コンパイルがデフォルトでは有効になっていません。
Razor は、HTML にインラインで、C# のコードを記述できて、非常に強力なのですが、レイアウトの調整や JavaScript のデバッグ時に、cshtml を編集するたびに実行するのでは、非常に手間がかかります。

ASP.NET Core では、Visual Studio のデバッグ実行状態で、.cshtml を編集して保存、ブラウザで該当ページをリロードして、変更内容を反映させるためには、コードに手を入れる必要があります。

ここでは、開発環境での実行時のみ、.cshtml の実行時コンパイルを有効にする手順を説明します。

補足ですが、ここでの開発環境での実行時とは、ASPNETCORE_ENVIRONMENT 環境変数が、Development に設定されている場合を指しています。Visual Studio では、ASP.NET Core プロジェクトの [プロパティ] - [デバッグ] から、起動プロファイル毎に、ASPNETCORE_ENVIRONMENT の値が設定できます。デフォルトは、Development に設定されています。
ASPNETCORE_ENVIRONMENT

起動時にどのプロファイルを使用するかは、デバッグ実行ボタンから選択できます。
Debug Button

RazorRuntimeCompilation パッケージの追加

ASP.NET Core プロジェクトに、RazorRuntimeCompilation を追加します。

[ソリューション エクスプローラー] - [<対象プロジェクト>] 選択し、右クリック メニューから、[NuGet パッケージの管理] を選択、[参照] を選択し、"RazorRuntimeCompilation" を検索し、"Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" パッケージをインストールします。
RazorRuntimeCompilation

Starup.cs の編集

Starup.cs を編集していきます。ConfigureServices メソッド内の "services.AddRazorPages()" を "services.AddRazorPages().AddRazorRuntimeCompilation();" とすれば、実行時コンパイルが有効になるのですが、今回は、開発環境でのみ実行時コンパイルが有効になるようにします。

Startup クラスのインスタンス生成時に、IWebHostEnvironment のインスタンスを保存するために、コンストラクタに引数を追加します。依存性の注入なので、既存のコンストラクタを編集して、引数を追加してください。

Startup.cs
//IWebHostEnvironment のインスタンス保存用
private IWebHostEnvironment _webHostEnvironment;

public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
   Configuration = configuration;
   //IWebHostEnvironment のインスタンスを保存
   this._webHostEnvironment = env;
}

次に、ConfigureServices メソッドを編集します。保存しておいた IWebHostEnvironment のインスタンスを参照し、デバッグ時のみ実行時コンパイルが有効になるように、AddRazorRuntimeCompilation をコールします。

Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    var mvcBuilder = services.AddRazorPages();

    if (this._webHostEnvironment.IsDevelopment())
    {
        //実行時コンパイルの有効化
        mvcBuilder.AddRazorRuntimeCompilation();
    }

以上で、開発環境での実行時のみ .cshtml ファイルの実行時コンパイルが有効となります。

Razor ファイルの実行時コンパイルは、開発時において非常に利便性が高いので、是非とも活用ください。

参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ループ中にリストの要素を削除する場合の注意点

リストをループで回している中で、そのリストの要素を削除する場合は、ループを逆順で回しましょう。

NG
        for (int i = 0; i < enemyList.Count; i++) {
            if (!enemyList[i].IsAlive) {
                enemyList.RemoveAt(i);
            }
        }
OK
        for (int i = enemyList.Count - 1; i >= 0; i--) {
            if (!enemyList[i].IsAlive) {
                enemyList.RemoveAt(i);
            }
        }

なぜ逆順にしなければならないのか?を示したものが以下の図になります。NG側では、要素Cを削除した際に後ろにある要素が一つ前に詰められる影響で、要素Dが正しく処理されない問題が発生しています。

figure.png

ちなみに、リストの要素を削除したいけどループ中に処理する必要はない時にはRemoveAllが便利です。

        enemyList.RemoveAll(enemy => !enemy.IsAlive);

参考リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む