C#学び直し(新)
もう一度、基礎から見直し学習する。メニューにある、C#、C#サンプル、C#サンプル2は過去の学習経過として残しておく
<静的クラスの要点>
- 入力パラメーターに対してのみ処理を行い、内部のインスタンス フィールドを取得したり設定したりする必要のない一連のメソッドを格納する便利なコンテナーとして使用しやすい
- クラスがプログラム内で最初に参照される前に、そのクラスが読み込まれ、そのフィールドが初期化され、その静的コンストラクターが呼び出されることが保証されている
- プログラムが存在するアプリケーションドメインの有効期間にわたってメモリに保持される
- 静的メンバーのみが含まれます
- インスタンス化できません(newが必要ない。プログラム起動直後にスレッドメモリにマップされているらしい)
- シールされています(継承不可)
- インスタンス コンストラクターを含めることはできません(静的コンストラクターでインスタンスは作れる。これはプログラム起動直後に呼び出されるらしい)
<new演算子に関しての要点>
- 値型がnew演算子によってインスタンス化すると、その内容の値は型の既定値にセットされる(int型であれば0になるstringならnull等)。メモリ確保はプログラムが起動した時点ですでに確保されている
- 参照型がnew演算子によってインスタンス化するとマネージヒープ上に動的にメモリが確保され内容の値は型の既定値にセットされる。その後コンストラクタが起動する
<型に関しての要点>
- varは基本プロパティ的なものに関して利用できない。例えば関数内の変数などには便利なので利用するとよい
- コンパイラは型情報を実行可能ファイル内にメタデータとして埋め込みます。共通言語ランタイム(CLR)は実行時に、このメタデータを使用してメモリの割り当て時および再要求時にタイプ セーフであるかどうかを再度確認します
- 最もよく使用される型はすべて System 名前空間に属している
- 型の形式を納めるSystem.Type型が存在する
- 型を調べるにはobject.GetType関数やtypeof演算子を利用します
- 型の互換性を調べるには as や is 演算子を利用する。as は互換性の成否をbool値で返す。is は互換性の成否を代入して返し正ならオブジェクトで非ならnullになる
<配列に関しての要点>
- 参照型である
- C#の配列はオブジェクトであり単なるアドレス指定可能な連続メモリ領域ではない
- 配列型は抽象基本型 Array から派生した参照型。この型は IEnumerable と IEnumerable<T> を実装するのでC#のすべての配列で foreach 反復処理を使用できる
- 配列型はArrayのプロパティ、メンバー、メソッドを利用できる
<クラスの要点>
- 参照型である
- new演算子によりインスタンス化されるとマネージヒープ上に動的にメモリが確保され値に規定値がセット、その後コンストラクタが起動する
- 確保されたメモリはガベージコレクションによって管理される(スコープを抜けるとメモリが破棄されたり等する)
- 継承はひとつしかできない(基本クラスを重ね間接的に複数継承する事はできる)
- インターフェイスは複数実装できる
- 「Custom c = new Custom();」これの左辺はポインタ(参照型)であり、右辺がない(インスタンス化していない)場合、内容はnull
<用語>
クラス |
オブジェクトの型を定義するコード |
クラスのオブジェクト |
ソフトウェアが扱おうとしている現実世界に存在する物理的あるいは抽象的な実体を属性(データ)と操作(メソッド)の集合としてモデル化しコンピュータ上に再現したもの。クラスは参照型であるためクラスオブジェクトの変数はマネージヒープ上のオブジェクトのアドレスへの参照を保持します。C#におけるオブジェクトはすべてObject クラスから暗黙的に派生しています(値型はValueTypeクラスを経由)。ToString()等はオーバーライドする事が可能 |
クラスのインスタンス |
クラスで指定された型のメモリが確保された状態のもの |
エンティティ |
一単位として扱われるデータのまとまり |
インスタンス化 |
new演算子によるオブジェクトの型のメモリ確保と考えると良い |
ヒープ |
動的に確保可能なメモリの領域。メモリの確保時や解放時にオーバヘッドがある |
既定のコンストラクター |
引数なしのコンストラクター |
パラメーター化されたコンストラクター |
引数ありのコンストラクター |
シングルトン |
インスタンスが 1 つだけあるクラスを作成すること。これはプログラム的に作成可能 資料:C# でのシングルトンの実装 |
値型に基づく変数は、値を直接含みます。ある値型の変数を別の変数に代入すると、含まれている値がコピーされます。
これは参照型の変数の代入とは異なります。参照型の変数の代入ではオブジェクト自体ではなくオブジェクトへの参照(ポインタのアドレスみたいなもの)がコピーされます。
値型はスタック上に割り当てられているか構造体にインラインで割り当てられています。参照型はヒープ上に割り当てられます。
参照型も値型もすべての基になっている基本クラス Object から派生しています。値型がオブジェクトのように動作する必要がある場合
値型を参照オブジェクトのように見せるラッパーがヒープ上に割り当てられ、その値型の値が割り当てられたラッパーにコピーされます
ラッパーはその中に値型が格納されていることがシステムにわかるようにマークされます。このプロセスはボックス化と呼ばれ
その逆のプロセスはボックス化解除と呼ばれます。ボックス化とボックス化解除によって、すべての型をオブジェクトとして扱うことができます。
メソッド(関数)にパラメータ(引数)として渡した場合
値型は関数内の処理で変更されない(値がコピーされている)
参照型は関数内の処理で変更される(参照されるので中身は書き変わる)
一般にクラスはより複雑な動作、つまりクラスオブジェクトの作成後に変更されることを意図されたデータをモデル化するために使用されます
構造体は主として構造体の作成後に変更されることを意図しないデータを含む小規模なデータ構造に最適です
<構造体の要点>
- プロパティにして「変数ではないため、~~~ の戻り値を変更できません。」というエラーが出た場合=>コンパイラ エラー CS1612を参照
- 値型である(メモリはスレッドスタックに割り当てられ、それが宣言されている型やメソッドと共に再利用される。=メモリ確保や破棄のオーバーヘッドが無い)
- クラスのような継承機能は持たない。インターフェイスの実装は可能
- 暗黙的な「既定のコンストラクター」を持ちnew演算子によるインスタンス化をしなくてもスレッド内にメモリ確保される(参照と違ってヒープ内ではない)
- newを使わなかった場合、中身の値は「無」なので、そのまま利用するとエラーが出る。利用前に値をセットすればOK
- new演算子を使って構造体をインスタンス化するとフィールドは規定値にセットされる
- 構造体内で「既定のコンストラクター」(引数無しのコンストラクター)を書くとエラーが出る(既に予約されていると考えると良い?)
- 構造体内で「パラメーター化されたコンストラクター」(引数有りのコンストラクター)を書くことは可能
- const または static と宣言されているインスタンスフィールド以外初期化できない
- 構造体は代入時にコピーされます。構造体を新しい変数に代入するとすべてのデータがコピーされ新しいコピーを変更しても元のコピーのデータは変更されません。この点は、Dictionary<string, myStruct> などの値型のコレクションを使用する際に重要です
- すべての構造体が System.ValueType を直接継承し、System.ValueType は System.Object を継承します。
最終更新:2013年06月08日 18:37