| 359 | |
| 360 | ==== Hello, World と返すモデル ==== |
| 361 | |
| 362 | そんなわけで、 Hello, World という内容のデータを取り出すことができるモデルを作ってみましょう。 Models フォルダの直下に C# ファイルを作ってしまっても良いのですが、業務内容を整理しやすくするため、サブフォルダを切ってからにしましょうか。まず、 Models フォルダを右クリックし、「追加」→「新しいフォルダー」を選択します。 |
| 363 | |
| 364 | [[Image(fig-model-new-folder.PNG, 640px, align=center)]] |
| 365 | |
| 366 | サブフォルダの名前は「!SmallCase」とでもしておきましょう。次に今作ったフォルダを右クリックし、「追加」→「クラス」を選択します。 |
| 367 | |
| 368 | [[Image(fig-append-model-01.PNG, 640px, align=center)]] |
| 369 | |
| 370 | [[Image(fig-append-model-02.PNG, 640px, align=center)]] |
| 371 | |
| 372 | 「新しい項目の追加」ダイアログが表示されます。「クラス」が選択されていることを確認して下さい。ファイル名は、「!HelloWorld.cs」としましょう。 |
| 373 | |
| 374 | 「OK」ボタンをクリックすると、 !SmallCase フォルダの下に !HelloWorld.cs ファイルが生成され、エディタで開いた状態になります。ファイルの内容は以下の通りになっているはずです。 |
| 375 | |
| 376 | {{{#!cs |
| 377 | using System; |
| 378 | using System.Collections.Generic; |
| 379 | using System.Linq; |
| 380 | using System.Web; |
| 381 | |
| 382 | namespace HelloWorld.Models.SmallCase |
| 383 | { |
| 384 | public class HelloWorld |
| 385 | { |
| 386 | } |
| 387 | } |
| 388 | }}} |
| 389 | |
| 390 | 名前空間 (`namespace` で始まる行で宣言されている名前ですね) の最後が `SmallCase`、クラス名が `HelloWorld` となっています。よくできてますねー。 |
| 391 | |
| 392 | それではこのクラスに、 Hello, World という文字列を返す'''プロパティ'''を追加してみましょう。プロパティとは、フィールド (メンバ変数) のように操作できるけど、その実態はメソッドのように振る舞いを持つ、というものです。今回は `get` のみを定義した読み取りアクセスのみ可能なプロパティを定義します。以下のように書いてください。 |
| 393 | |
| 394 | {{{#!cs |
| 395 | public class HelloWorld |
| 396 | { |
| 397 | // Hello, World を返す Text プロパティ |
| 398 | public string Text |
| 399 | { |
| 400 | get |
| 401 | { |
| 402 | return "Hello, World"; |
| 403 | } |
| 404 | } |
| 405 | } |
| 406 | }}} |
| 407 | |
| 408 | こう書くことによって、このクラスのオブジェクトを使用する側のプログラムでは、以下のように書くことができます。 |
| 409 | |
| 410 | {{{#!cs |
| 411 | var hw = new HelloWorld.Models.SmallCase.HelloWorld(); |
| 412 | var output_text = hw.Text; // "Hello, World" をここで取得 |
| 413 | }}} |
| 414 | |
| 415 | C# に慣れていない人のために順を追って解説しましょう。まず、 `var` という修飾子は、ここで定義する変数の型を推測することを意味します。'''型推論'''はコンパイル時に行われ、代入しようとする値と同じ型の変数であるとみなされます。つまり、上記のコードは以下のコードと本質的には同じ意味です。 |
| 416 | |
| 417 | {{{#!cs |
| 418 | HelloWorld.Models.SmallCase.HelloWorld hw = new HelloWorld.Models.SmallCase.HelloWorld(); |
| 419 | string output_text = hw.Text; |
| 420 | }}} |
| 421 | |
| 422 | なんでこう書かないのかというと、 2回も `HelloWorld.Models.SmallCase.HelloWorld` などという長ったらしい名前を書くのはさすがに冗長すぎるからです…。 |
| 423 | |
| 424 | 次になぜ `Text` プロパティをわざわざプロパティとして実装したかというと、仮に単なるフィールドとして実装した場合、 |
| 425 | |
| 426 | {{{#!cs |
| 427 | public class HelloWorld |
| 428 | { |
| 429 | // Text をフィールドとして実装した場合 |
| 430 | public string Text = "Hello, World"; |
| 431 | } |
| 432 | }}} |
| 433 | |
| 434 | 呼び出し側のプログラムで、このフィールドを書き換えることができてしまいます。今回のケースはともかく、こうした使われ方はビジネスロジックの設計者にとっては意図していないものである可能性があります。 |
| 435 | |
| 436 | {{{#!cs |
| 437 | var hw = new HelloWorld.Models.SmallCase.HelloWorld(); |
| 438 | hw.Text = "Gooby, Past"; // Hello, World じゃなくなっちゃった…。 |
| 439 | }}} |
| 440 | |
| 441 | 本質的には C# のプロパティはメソッドの構文糖衣に過ぎません。プロパティでできることは全てメソッドでも実現可能です[[FootNote(デスクトップアプリケーション作成で WPF を使う場合にビューモデルオブジェクトをビューにバインドする際、バインドするステータスは変数のようにアクセスできる必要があるという仕様があって、そういうケースではメソッドで代用できる必要がある、といったような例外はありますが…。)]]。とはいえ、プロパティを用いることでプログラムの表現がより直感的になるケースも多いですし、 C# では広く使われている書き方ですので、この際知っておくといいと思います。 |
| 442 | |