CodeBehind vs CodeFile (1)

#背景
いままでのASP.NET開発では、特に意識せずにVisual Studio既定のCodeBehind属性を使っていました。
ただ、Sitecoreを調べていくうちに、あえてCodeBehindからCodeFileに変更している事例が散見されました。
このため、事例の背景を正しく理解するためにCodeBehindとCodeFileの違いについて調べてみました。
 
#準備
1. ASP.NET 空のWeb アプリケーションを作成します。
1. Webフォーム「CodeBehind.aspx」と「CodeFile.aspx」を追加します。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/82737/4c5e76eb-2c0b-7df3-7736-570a697957d1.png)

1. ローカルIISを使うように設定します。
1. 以下のようなコードを入力します。

●CodeBehind.aspx

```aspx-cs
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CodeBehind.aspx.cs" Inherits="WebApplication.WebForm" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label ID="lbl" runat="server" Text="default" />
        </div>
    </form>
</body>
</html>
```
●CodeBehind.aspx.cs

```csharp
using System;

namespace WebApplication {
    public partial class WebForm : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            lbl.Text = "code bihind!!(●ω●;)";
        }
    }
}
```

●CodeFile.aspx

```aspx-cs
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CodeFile.aspx.cs" Inherits="WebApplication.CodeFile" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label ID="lbl" runat="server" Text="default" />
        </div>
    </form>
</body>
</html>
```

●CodeFile.aspx.cs

```csharp
using System;

namespace WebApplication {
    public partial class CodeFile : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            lbl.Text = "code file...(´･ω･`)";
        }
    }
}
```

#実験と結果
##ビルドしないで、各aspxにリクエストしてみる。
1) CodeBehind.aspx
　→　エラーとなる。
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/82737/e96b8db5-f66c-dcc3-423b-6a4f9bb9b2f7.png)

2) CodeFile.aspx
 　→　エラーとならない。![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/82737/3c00af69-1e90-b646-43a8-20fa7b027f63.png)
  **→CodeFileの動的コンパイルのため**


##サーバーコントロールを各aspxに貼り付けてみる。
Labelコントロール（ID：Label1）をもう一つ、ツールボックスからドラッグ＆ドロップで貼り付けてみる。
1) CodeBehind.aspx
　→　CodeBehind.aspx.designer.csに自動的にLabel1の定義が記述される。
2) CodeFile.aspx
　→　CodeFile.aspx.designer.csにLabel1の定義が記述されない。

```csharp
 //CodeBehindだと書かれます
 protected global::System.Web.UI.WebControls.Label Label1;
```

##ビルドしてできたDLLをILSPYで逆コンパイルしてみる。
CodeBehindクラスもCodeFileクラスも両方存在する。
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/82737/fa56792b-85fb-9128-3516-1e9c821853a0.png)
(これはcsファイルのビルドアクションが既定で"コンパイル"であり、そのままにしていたため。CodeFile.csとCodeFile.designer.csのビルドアクションを"コンテンツ"に変えれば、DLLには含まれなかった)

##ビルド後にCodeFile.csのロジックを変更してリクエストしてみる。
　ビルド後にCodeFile.csを以下のように書き換える。
　(※CodeFile.csのビルドアクションはコンパイルにしておく)

```csharp
using System;
namespace WebApplication {
    public partial class CodeFile : System.Web.UI.Page {
        protected void Page_Load(object sender, EventArgs e) {
            lbl.Text = "code file!!!(｀・ω・´)"; //←ここを変更
        }
    }
}
```
ビルドしないでリクエストしてみると、変更後のコードが実行された。

![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/82737/2bcd66cf-c110-8cdf-247e-5614fa979baa.png)
**→ dll内の処理よりcsファイルの処理が優先されることがわかる**

##ビルド後にCodeFile.csをリネームしてリクエストしてみる。
Codefile.cs　→　-Codefile.cs
Codefile.designer.cs →　-Codefile.designer.cs

エラーとなる。
![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/82737/03301844-159b-58d3-87cd-2c5a7d70bc7c.png)
**→ そもそもdllを見に行ってないことがわかる**

#まとめ
1. CodeBehind属性は予めビルド済みのDLLが必須。csファイルは不要(あっても使わない)
2. CodeFile属性は予めビルド済みのDLLは不要(あっても使わない)。csファイルは必須。
3. CodeBehind属性は貼り付けたサーバコントロールの参照がdesigner.csに自動生成される。CodeFile属性は自動生成されない。

#関連
[CodeBehind vs CodeFile (2)](http://qiita.com/Mr_K/items/d3006288571687240659)