Introduction to C#.

Similar presentations


Presentation on theme: "Introduction to C#."— Presentation transcript:

1 Introduction to C#

2 アジェンダ .NET概説 基本要素 オブジェクト指向サポート インターフェース イベント/デリゲート 例外処理 GC リフレクション
モジュール配布

3 .NET概説

4 .NET概説 .NETとは .NETによって変わること .NET Frameworkのメリット .NET対応言語 C#とは

5 .NETとは .NET 単に 「.NET」 と言うときは、 「.NET 戦略」 を指す。 すなわち、 Microsoft の戦略を表す言葉で、 一言で表すと 「アプリケーションから Web サービスへ」 となる。 .NET Framework .NET 戦略にふさわしい、 次世代 OS を意味する。 最初は、 Windows の上に .NET Framework という 「皮」 を被せて実現する。

6 .NETによって変わること x86からMSILへ WindowsAPIからCLRへ COMからBCLへ 言語間の垣根が低くなる
x86CPU用のマシン語→ MSIL (CPUに依存しない中間言語) WindowsAPIからCLRへ 複雑になったWindowsAPI→新設計のCLR(実行環境) COMからBCLへ COM→CLR上に構築されたBCL(基本クラスライブラリ) 言語間の垣根が低くなる .NET対応言語は共通してCLS規格を満たしている レジストリから.cfgファイルへ レジストリ→cfgファイル(テキストファイル) アセンブリのバージョン管理 使用する共有アセンブリのバージョン指定が実行時に必須となり、dllバージョン不一致が解消される。

7 .NET Frameworkのメリット プログラムの安全な実行 アプリケーションの容易な配布 マルチ言語の開発環境
プログラムの実行がCLRによって管理されることでGCやタイプセーフの恩恵を受ける。 アプリケーションの容易な配布 インストール時にレジストリ登録などが不要。 バージョン管理機能を持っている。 マルチ言語の開発環境 C#やVB.NETなど複数のプログラミング言語を使ってひとつのものを作ることができる。 過去のソフトウェア資産を活用できる。

8 .NET対応言語 .NET対応の言語はCLS規格にのっとっているため、出来ることは(だいたい)同じである。
どの言語を使ってもコンパイルすればCLSにのっとったMSILになる。

9 C#とは シンプルかつ強力 バグの作りこみを防ぐ言語仕様 習得しやすい プログラムの安全な実行 相互運用性
ヘッダファイルとマクロ機能、多重継承の廃止 バグの作りこみを防ぐ言語仕様 if(a=b)などはコンパイルエラーになる ポインタを原則的に廃止 習得しやすい ベースクラスライブラリはC#、VB.NET等で共通 C/C++の構文の多くを踏襲している プログラムの安全な実行 GCによるメモリリークの防止やタイプセーフなどがCLRによって実現されている 強力な構造化例外処理機構 相互運用性 COM+をフルサポート Win32APIのようなネイティブコードを直接呼び出せる

10 .NETの仕組み 実行手順 どの言語を使ってもソースコードをコンパイルすると中間言語(MSIL)になる。
.NET対応言語(C#など)で書かれたソースコード どの言語を使ってもソースコードをコンパイルすると中間言語(MSIL)になる。 実行時はJITコンパイラによってプラットフォームに依存した命令になる。 .NET対応コンパイラ DLL or EXE のアセンブリ(MSILとメタデータ) .NET開発環境 ・クラスローダ ・Just In Timeコンパイラ プラットフォームに依存した命令 実行 .NET実行環境

11 基本要素

12 基本要素 値と参照 System.Object “const”キーワード アクセス修飾子 パラメータ修飾子 “namespace”

13 値と参照 C#のデータタイプは「値型」か「参照型」のみ 値ベースのタイプ 参照ベースのタイプ
値データタイプ(整数、浮動少数点、boolなど) 列挙型 構造体 参照ベースのタイプ クラス Object String 配列 デリゲート

14 値タイプと参照タイプの違い 相違点 値 参照 アロケート場所 スタック ヒープ ベースタイプ System.Value
Sealedでない任意のタイプ 他のベースタイプになれるか 不可 パラメータで渡されたときは 参照(変数のアドレスが渡される) 破棄のタイミング スコープを抜けたとき GCが働くとき RefandValを実行

15 System.Object C#のすべての型のベースクラス 以下のメンバを持つ Equals:参照を比較
GetHashCode:インスタンスを識別する GetType:現在参照しているオブジェクトのType            を戻す ToString:<名前空間>.<クラス名>を返す Finalize:オブジェクト破棄前に呼ばれる MenberwiseClone:簡易コピーを作成する

16 Object型の提供メソッド オーバーライド可能 注意するメソッド GetType MemberwiseClone RTTIを行うために利用
EqualsはFALSEを返す ReferenceEqualsはFALSEを返す MemberwiseClone MemberwiseCloneを参照

17 “const”キーワード “const”キーワードを利用して、定数データタイプを作成する 利用するシナリオ: クラス内定数 定数クラスを作成
全インスタンスに定数を持たせることが可能 定数クラスを作成 C# ではグローバル変数を定義できないので この場合、コンストラクタを“private”にしてインスタンス生成を防ぐ

18 パラメータ修飾子 修飾子 説明 (なし) 値が変更されない入力パラメータ out 呼び出されたメソッドで値が変更される ref
呼び出し側、呼び出されたメソッド内で値が更新される params 複数パラメータを送る

19 注意:“out”と“ref” “out”と“ref”は呼び出し側でも記述する “out”と“ref”の違い “ref”初期設定の理由
object.method(i, out j); object.method(i, ref j); “out”と“ref”の違い out:呼び出し側で初期化する必要なし ref:呼び出し側で初期化する必要あり “ref”初期設定の理由 メソッドのパラメータに参照を渡す 未初期化で渡すと、NULLポインタを渡すことになる

20 例:outとref 実装側 呼出側 class clsParameterModifier { // outの例
  public void Add(int a, int b, out int ans){    ans = a + b;   }   // refの例   public void ChangeToUpperString(ref string s){     s = s.ToUpper();   // paramsの例   public void DispParams(params object[] list){     for(int i = 0; i < list.Length; i++){       if(list[i] is Temp){         Console.WriteLine("This is Temp.\n");       }else{         Console.WriteLine("This isn't Temp.\n");       }     } } static void Main(string[] args) {   int i = 90, j= 30, k; // Add用   string s = "this is a pen.";// ChangeToUpperString用   Temp t = new Temp();// DispParams用   clsParameterModifier c = new clsParameterModifier();   // Addのチェック c.Add(i, j, out k); // "out"と書きましょう   Console.WriteLine(" = {0}.\n", k);   // ChangeToUpperStringのチェック   Console.WriteLine("Before:{0}", s);   c.ChangeToUpperString(ref s); // "ref"と書きましょう   Console.WriteLine("After:{0}", s);   // DispParamsのチェック(可変化)   c.DispParams(1,2,3,4,5,t); }

21 namespace 独自クラスをグループ化する 作成したクラスなどを 複数のcsファイルをひとつのnamespaceにできる
namespace呼び出しには“using”を利用する 命名は慎重に・・・ 利用しているnamespaceでクラスなどの名前が同一の場合は、完全修飾名で指定

22 オブジェクト指向サポート

23 オブジェクト指向サポート オブジェクト指向の基本 カプセル化 継承 ポリモーフィズム

24 オブジェクト指向の基本 C#は、オブジェクト指向言語である オブジェクト指向の基本3要素 カプセル化:オブジェクトの内部を隠す
継承:コードの再利用(“is-a”と“has-a”) ポリモーフィズム:目的のオブジェクトを動的に利用する( “is-a” 時のみ可能)

25 カプセル化 “readonly”キーワード プロパティ化 静的コンストラクタ 「読み込み」のみ可能 “get”と“set” 静的プロパティ
クラス単位で利用 普通のプロパティと同様に操作可能 静的コンストラクタ 静的メンバを初期化するために利用 可視性のキーワードを指定できない

26 継承 “is-a” “protected”キーワード “base”キーワード “sealed”キーワード
メンバを子クラスからアクセス可能にする “base”キーワード ベースクラスのコンストラクタを呼ぶ デフォルトコンストラクタを呼ばないので、パフォーマンス向上 “sealed”キーワード “is-a”継承を禁止する “has-a”継承は可能

27 例:“base”キーワード ベースクラス サブクラス class Manager : Employee { class Employee
    public int supNum; /*   // ノーマルなコンストラクタ     public Manager(int SupNum, int empID, int Length)     {         supNum = SupNum;         EmpID = empID;         Length = Length;     } */ // "base"キーワードを利用したコンストラクタ public Manager(int SupNum, int empID, int Length) : base (empID, Length)      supNum = SupNum; } class Employee {   public int EmpID;   public int Length;   public Employee(){}   public Employee(int empID, int length)   {     EmpID = empID;    Length = length;   } }

28 継承 “has-a” 外側のクラスを親クラス、含まれる側のクラスを子クラスと呼ぶ 子クラスは“private”メンバとする
“is-a”継承のベースクラス、サブクラスとの違いに注意 子クラスは“private”メンバとする カプセル化のため 子クラスの初期化は、親クラスのコンストラクタで行うのが基本 子クラスへのアクセスは、親クラスでメソッドを実装しておこなわれる(委譲)

29 ポリモーフィズム 1 サブクラスでオーバーライドするメンバは“public”で宣言する
“base”キーワードを利用してデフォルトの実装を呼び出し可能 “new”キーワードで仮想メソッドの継承を断ち切ることができる ベースクラスとメソッドが同名だが互換性が無い場合に利用

30 “new”キーワード Object Shape Squre Cube
左図のような継承を行うとき、「Cube」クラスが上位クラスのメソッドを継承させないようにするために、“new”キーワードを利用する public class Cube : Squre { // 他の実装 // 継承されたメソッドを隠蔽する public new void Draw() // 実装 } AbstractなDrawメソッド Shape Squre Drawメソッドの実装 Cube Squre.Drawメソッドを隠蔽した新しい実装

31 ポリモーフィズム 2 “abstract”キーワードを利用してベースクラスの作成を禁止する
abstract public class Shape Shape s1 = new Shape(); { =>コンパイルエラー!!不可 // 実装 } このようにすることで、 Shapeクラスをインスタンス化させないようにする “abstract”キーワードを利用して“純粋仮想メソッド”にすることで継承側で実装を強制する

32 インターフェース

33 インターフェース 概要 明示的な実装 インターフェース参照の取得

34 インターフェース 概要 データタイプを定義できない メソッドのデフォルト定義を実装できない 多重継承可能 継承したクラスに実装を強制する
クラスでは無理 public class Triangle : Shape, Line <=コンパイルエラー!! public class Triangle : IShape, ILine <=インターフェースなのでO.K.

35 インターフェース 明示的な実装 継承したインターフェース、またはクラスが同じメソッド名を保有している場合に利用 以下のように実装する
public class : Shape, IShape { // これはShapeクラス public override void Draw(){ ///実装 } // これはIShapeインターフェース // アクセス修飾子が必要ない void IShape.Draw(){ ///実装 } }

36 インターフェース 参照の取得 インターフェースは、インターフェース型でキャストすれば直接参照可能 “as”でのキャスト
クラスがインターフェースを継承していないとInvalidCastException例外発生 “as”でのキャスト クラスがインターフェースをサポートしていない場合は、例外を起こさずNULLをセットする “is”を利用して互換性チェック可能 if(“オブジェクト名” is “インターフェース名”)

37 例:“as”と“is” Something1 s1 = new Something1();
IShape i; // 普通のキャスト try{     i = (IShape)s2; // 例外発生 }catch{     Console.WriteLine("The InvalidCastException occurs."); } // "as"を利用したキャスト i = s2 as IShape; // 例外は発生しない if(i != null) {     Console.WriteLine("This class inheritances IShape."); }else{     Console.WriteLine("This class doesn't inheritances IShape."); // "is"を利用した互換性チェック // s1,s3 => Yes, s2 => No if(s1 is IShape){ // “true”か”false”が返される。ここは“true”。     Console.WriteLine("Yes.");     Console.WriteLine("No."); public interface IShape {     void Draw(); } public abstract class Shape     public abstract void Draw(); public class Something1 : IShape     void IShape.Draw(){ Console.WriteLine("1"); } public class Something2 : Shape     public override void Draw(){ Console.WriteLine("2"); } public class Something3 : Shape, IShape    void IShape.Draw(){ Console.WriteLine("3 for inter"); }    public override void Draw(){ Console.WriteLine("3 for class"); }

38 イベント/デリゲート

39 イベント/デリゲート コールバック デリゲートの定義 イベントとは? イベントのリッスン イベントのデザイン

40 コールバック C/C++で利用されていた技術 実体は「関数ポインタ」 欠点は、 この問題解決のため“デリゲート”が作られた
関数が他の関数に情報を返すときに利用 実体は「関数ポインタ」 欠点は、 呼び出し側に型情報を示せない タイプセーフにできない 関数名=型名 この問題解決のため“デリゲート”が作られた

41 デリゲートの定義 実体は、関数ポインタをラップするクラス 登録する関数の戻り値、パラメータなどは自由 関数の実装は、同クラス/他クラスでも可
Targetプロパティで、実装クラス名の取得可能 任意の数の関数を登録できる 内部的に関数ポインタのリンクがある “combine”または“+”演算子で追加可能 “remove”で削除

42 イベントとは? 実行時に呼び出す関数を指定する方法 イベント処理の手順
例外程深刻ではない障害が発生したときなどに、処理する関数を呼び出すのに利用する イベント処理の手順 “event”キーワードでイベントを定義 イベント発生時に呼び出す関数を定義 デリゲート関数を利用

43 イベントのリスニング イベントを定義したクラスを利用するときには、イベントハンドらとして定義されている“delegate”メソッドを実装する
オーバーロードされた演算子でイベントハンドラを登録する “+=”:イベントハンドラに追加 “ー=” :イベントハンドラから削除

44 例:イベントハンドラへの登録 // イベントハンドラを利用したコード // イベントを発生し、delegateメソッドも定義されいるクラス
public class Line {   public static int i;   // イベント発生時に呼び出す関数(デリゲート関数)   // パラメータは"string"、戻り値は"void"   public delegate void LineEventHandler(string s);   // このクラスが発生させるイベント   // public static event (定義したdelegateメソッド) 任意のイベント名   public static event LineEventHandler Erase;   public static event LineEventHandler Add;   public static event LineEventHandler Uphold;   // イベントを発生させるメソッド   public void MakeEvent()   {// イベントを発生させる     Erase("Erase"); // "Erase"イベント発生     Add("Add");  // "Add"イベント発生     Uphold(“Uphold”); // “Uphold”イベント発生   } } // イベントハンドラを利用したコード // Lineオブジェクト作成 Line l = new Line(); // イベントをフックする Line.Erase += new Line.LineEventHandler(EventLine.OnErase); Line.Add += new Line.LineEventHandler(EventLine.OnAdd); Line.Uphold += new Line.LineEventHandler(EventLine.OnUphold); // イベントを発生する l.MakeEvent(); // イベントを切り離す Line.Erase -= new Line.LineEventHandler(EventLine.OnErase); Line.Add -= new Line.LineEventHandler(EventLine.OnAdd); Line.Uphold -= new Line.LineEventHandler(EventLine.OnUphold);

45 イベントのデザイン イベント発生側 イベント処理側 イベントを処理する“delegate”メソッドを定義 発生するイベントをリストアップ
型に従い、イベントハンドラ用のクラス/インターフェースを作成 ハンドラの実装を行う

46 例外処理

47 例外処理 例外とは? System.Exceptionクラス try~catch~finally “例外”のスロー
“using”ステートメント “例外”の設計

48 例外とは? 既存のエラーコードの短所 SEH(構造化例外処理)は、従来のエラー処理では対処できない障害を検出するための機能
処理できないイベント ランタイムエラー トラップ etc. エラーコードの多様化による統一性の欠如 #define => WIN32 API HRESULT => COM etc.. SEH(構造化例外処理)は、従来のエラー処理では対処できない障害を検出するための機能

49 System.Exceptionクラス .NET Frameworkでは、例外の実体はExceptionの継承オブジェクト
StackTrace: エラーが発生した位置を判別するときに利用 InnerException: 「“例外”処理中に発生した/する例外」を処理する際に利用 元々の原因となった例外を格納する

50 例:“InnerException” public class MyAppException:ApplicationException {
public MyAppException (String message) : base (message) {} // “Exception”クラスには“String”と // "Exception"をパラメータに持つコンストラクタがある public MyAppException (String message, Exception inner) : base(message,inner) {} } public class ExceptExample { public void ThrowInner () throw new MyAppException("ExceptExample inner exception."); } public void CatchInner() // “Main”でこの関数を呼ぶ try { this.ThrowInner(); //最初の例外をスロー }catch (Exception e) { // ここでの例外の原因は、上の"this.ThrowInner();" // なので、InnerExceptionにはこの例外をスローする // 元々の原因となった“e”を設定し、再スローする throw new MyAppException("Error caused by trying ThrowInner.", e);

51 try~catch~finally 例外が発生するコードを“try”ブロックで囲む “try”に対応する“catch”ブロックを記述
オブジェクトの生成 3rdパーティのクラスのメソッド呼び出し etc.. “try”に対応する“catch”ブロックを記述 例外発生時、処理は“catch”に移動 発生しない場合は, “catch”ブロックは処理されない “finally”ブロックは必ず実行される オプションなので、作成は必須ではない オブジェクトのリリースなどの後処理を記述する 記述は、“using”ステートメントを考慮 => 後述

52 “例外”のスロー 例外がスローされるタイミング “Exception”クラスを継承して、独自の例外クラスを作成できる システムが例外を検出
.NET Framework SDKにリストがある “throw” 任意のタイミングで例外を発生できる “catch”ブロック内で再スロー可能 呼び出し側の“catch”では再スローされた例外を処理 “Exception”クラスを継承して、独自の例外クラスを作成できる

53 “using”ステートメント “using”を利用すると、オブジェクトのクリーンアップを行う
コンパイラが自動的に“try~catch”ブロックを作成 “finally”ブロック中で、“Dispose”メソッドを呼び出す “Dispose”メソッドをサポートしていないオブジェクトには利用できない

54 例:“using”ステートメント “using” 未使用 “using” 使用 コンパイラは両方のコードをまったく同じネイティブコードにする
class app { try { Byte b = new Byte[]; // 実装 } catch { finally{ if(b != null) ((IDisposable)b).Dispose(); “using” 使用 class app { using(Byte b = new Byte[]){ // 実装 } コンパイラは両方のコードをまったく同じネイティブコードにする

55 “例外”の設計 これまで、例外処理は「パフォーマンスが悪くなる」と言われていた
原因: 例外発生時、インスタンス化されたオブジェクトをクリアするため独自にトラップフレームを用意 =>そのため、“try”ブロックを狭くしていた .NETでは、GCがあるためトラップフレームを考慮する必要なし “try”ブロックを広くできる “catch”ブロックは考慮できる例外ごとに記述 “finally”ブロックでは、メモリ開放以外の後処理 “using”ステートメント

56 GC

57 GC 概要 Finalizeメソッド IDisposableインターフェース ジェネレーション

58 GC 概要 オブジェクトの有効期間 ヒープ領域を明示的に開放するために “new”されたオブジェクトはヒープ領域に置かれる
.NETランタイムがメモリ領域を管理 ヒープ領域は、プロセスが存在する間は開放されない ヒープ領域を明示的に開放するために “Finalize”メソッド “IDisposable”インターフェース

59 オブジェクト生存期間 メモリの確保や解放などは自動で行う。 アプリケーションでオブジェクトを作成すると自動でメモリが確保される。 GC概要
管理ヒープ領域 メモリ管理機能 (メモリの確保・解放) メモリの確保や解放などは自動で行う。 アプリケーションでオブジェクトを作成すると自動でメモリが確保される。

60 GC概要 GCの動作 メモリ管理機能 (メモリの確保・解放) メモリ管理機能 (メモリの確保・解放) 管理ヒープ領域 管理ヒープ領域 GC後
これらの領域を開放 :未参照領域

61 ヒープ上の全てのオブジェクトには、特定のジェネレーションが設定されている
GC概要 GCの動作 ヒープ上の全てのオブジェクトには、特定のジェネレーションが設定されている 0:新たに配置されたオブジェクト 1:GCのスイープ後に残ったもの 2:GC後に残ったもの GCは、最初に「0」のものからスイープをはじめ、十分にメモリを確保したらスイープを中止して次のジェネレーションに昇進する このため、参照が無くてもメモリ上にオブジェクトが存在することに注意

62 誰からも参照されていないオブジェクトは削除される。
GC概要 GCタイミング 誰からも参照されていないオブジェクトは削除される。 しばらく実行していると“参照されているオブジェクト”と“誰からも参照されていないオブジェクト”が混在する状況になる 参照されていないオブジェクトが削除される 削除するタイミングは全てGCに一任されているが、一般的にはヒープ領域が不足してきた時に行われる

63 GC Finalizeメソッド Finalizeメソッド = デストラクタ + GC機能
“new”を使ってC#オブジェクトを作成すると、ランタイムは“Finalize”をサポートしているかをチェックする サポート時は、オブジェクトを「ファイナライゼーションキュー」に格納 GC時、ランタイムはFinalizeメソッドをコール このオーバヘッドで、メモリからの開放のタイミングが遅くなる

64 GC Finalizeメソッド コード GCが起動すると、ランタイムはメモリを開放 マネージヒープ o1 o2 o3 o4
Sample1 o1 = new Sample1(); Sample2 o2 = new Sample2(); Sample3 o3 = new Sample3(); Sample4 o4 = new Sample4(); GCが起動すると、ランタイムはメモリを開放 マネージヒープ o1 o2 o3 o4 GCがクリアするタイミングでFinalizeをコール Finalizeをサポートすると、ランタイムはマークをつけてヒープに格納する o2 o4 ファイナライゼーションキュー

65 GC IDisposable デストラクタでは、クリアのタイミングは呼出側では制御できない
リソースの明示的な破棄をサポートする “Dispose”メソッド内では、“SuppressFinalize”メソッドを呼び出すこと GC時、“Finalize”の呼び出しを行わなくなる

66 リフレクション

67 リフレクション 取得できる情報 “Type”クラス “Reflection”クラス レイトバインディング
クラスのフィールド、メソッド、プロパティなどの値を取得 “Reflection”クラス レイトバインディング “Activator”クラス COMのIDispatchインターフェースを取得するときに利用

68 リフレクションの意義 リフレクションの実体 リフレクションの利用シナリオ
CLRをターゲットとする全モジュールが持つ「メタデータ」は、モジュールの情報をもつ リフレクションは、モジュール内のメタデータに対するオブジェクトモデル リフレクションの利用シナリオ レイトバインディング時に、利用するアセンブリの型をチェック アセンブリの全モジュールのメタデータを調査

69 取得できる情報 1 Assembly アセンブリを定義または読み込み アセンブリ マニフェストにリストされているモジュールを読み込み
そのアセンブリから型を検索し、そのインスタンスを作成 Module モジュール内のクラスなどの情報 グローバル メソッド、モジュールに定義されている固有の非グローバルなメソッド ConstructorInfo コンストラクタの実装詳細 (abstract または virtual など) 名前、パラメータ、アクセス修飾子 (public または private など) 特定のコンストラクタ呼び出し:Type オブジェクトの GetConstructors メソッドまたは GetConstructor メソッド MethodInfo 名前、戻り値の型、パラメータ、アクセス修飾子 (public または private など) メソッドの実装詳細 (abstract または virtual など) 特定のメソッドを呼び出し:Type オブジェクトの GetMethods メソッドまたは GetMethod メソッド

70 取得できる情報 2 FieldInfo フィールドの名前、アクセス修飾子 (public または private など)
フィールドの実装詳細 (static など) フィールドの値を取得または設定 EventInfo 名前、イベント ハンドラのデータ型、カスタム属性、宣言型、イベントのリフレクションされた型 イベント ハンドラを追加および削除 PropertyInfo プロパティの名前、データ型、宣言型、リフレクションされた型、読み取り専用または書き込み可能のステータスなどの情報を探索 プロパティの値を取得または設定 ParameterInfo パラメータの名前、データ型、パラメータが入力パラメータか出力パラメータかなどの情報を探索 メソッド シグネチャ内のパラメータの位置を探索

71 “Type”クラス 実行時にクラスの情報を取得するための方法 取得できる情報 取得される情報は配列で返される
“GetType”メソッドで取得 取得できる情報 メソッド インターフェース プロパティ 取得された値のタイプをチェックするメソッドもある IsAbstract,IsArray,etc… 取得される情報は配列で返される

72 “Reflection”クラス “Assembly”クラス クラスの情報と同様に情報を列挙できる
アセンブリを動的にロードする Load(“名前空間”) LoadFrom(“モジュールのフルパス”) 識別子はアセンブリの名前空間 クラスの情報と同様に情報を列挙できる 指定アセンブリ内の指定クラスのメンバ情報も取得できる

73 例:“GetType” 左の例では、“ConsoleApplication1”内に“SampleType”クラスが存在する
public void AllTypeList(Assembly a) { Type[] types = a.GetTypes(); foreach(Type t in types) Console.WriteLine("Type = {0}", t); } // 指定メソッドを表示 public void AllMemberList(Assembly a) // SampleTypeタイプを取得 Type type = a.GetType("ConsoleApplication1.SampleType"); // SampleTypeを作成する object obj = Activator.CreateInstance(type); // メソッドの情報を取得 MethodInfo mi = type.GetMethod("SampleMethod"); // メソッドを呼び出す(パラメータなしの場合はnull) mi.Invoke(obj, null); 左の例では、“ConsoleApplication1”内に“SampleType”クラスが存在する クラス内のメソッドは、“GetMethod”および“Invoke”を利用して呼び出す

74 レイトバインディング ほとんどのモジュールはアーリーバインディングにするべき “Activator”クラス
アーリーバインディング:コンパイル時にエラー検出 レイトバインディング:実行時に自身が記述したコードで整合性をチェックする “Activator”クラス “CreateInstance”メソッドでモジュール内の指定したクラスをインスタンス化 “Invoke”メソッドを使って指定クラスのメソッドを呼び出す 呼び出しメソッドがパラメータを持つ場合は,配列にして渡す

75 モジュール配布

76 モジュール配布 アジェンダ アセンブリ プライベート 共有 “config”ファイル 共有名(ストロングネーム) バージョンポリシー 配布

77 アセンブリ 既存の“EXE”や“DLL”の.NET版 アセンブリには、「プライベート」と「共有」の2種類ある ロケーション
バージョンやコレクションを自己記述している .NETでは、アセンブリが配布の単位となる アセンブリには、「プライベート」と「共有」の2種類ある プライベートアセンブリの配布は「side by side」 共有アセンブリは、GACに配布 ロケーション プライベートはconfigファイルで設定 共有はGACに配布 GACの場所は“machine.config”で設定

78 .NET アプリケーションの構造 A.Dll メタデータ モジュールがアプリと同じフォルダにあれば“プライベート”、GACにあれば“共有”
マニフェスト MSIL 関連他ファイルの参照情報 B.dll タイプメタデータ MSILのコード メタデータ これらの場所を“config”ファイルで指定する MSIL アセンブリにマニフェストは一つ マニフェスト内に他アセンブリの参照情報を保持 コンパイラの“/addmodule”フラグを指定して作成

79 “config”ファイル アプリケーションが利用するアセンブリを明示的に指定する
マシン全体の構成は“machine.config”ファイルで設定する ファイル名は“アプリケーション名.config ” 利用するには“Assembly.cs”ファイルでバージョン指定が必須 “AssembluVersion”属性で指定 デフォルトでは“1.0.*”なので、変更は必須 Private_Assemblyにサンプル有り

80 バージョンポリシー アプリケーションのバージョンはデフォルトでは未設定 バージョンポリシー “AssemblyVersion”で設定する
メジャー マイナー リビジョン ビルド   多分  互換性有り 互換性有り QFE メジャー、マイナーが異なると互換性なしとみなしバインドが失敗する リビジョン番号だけ異なる場合は、動作保証なしだがバインド成功 ビルド番号だけ異なる場合は,互換性ありとみなしバインド成功

81 共有名(ストロングネーム) 共有アセンブリは、複数のアプリケーションから利用可能 共有名付きアプリケーション作成方法 GACに配置される
GACの位置は、“machine.config”で設定 共有名付きアプリケーション作成方法 “sn.exe”を利用して共有名を持つファイルを作成 “Assembly.cs”ファイルで、“AssemblyKeyFile”属性を共有名を保持するファイルパスに設定する “gacutil.exe”でGACにインストール

82 配布 アセンブリのバージョンポリシーをしっかり決める “プライベート”なら、基本は“side-by-side” “共有”なら、GACに配布
要素は“メジャー”、“マイナー”、“リビジョン”、“ビルド” “AssemblyVersion”属性でバージョンを設定 “プライベート”なら、基本は“side-by-side” “config”ファイルを利用して配布を設定 ロケーション(“privatePath”属性) “共有”なら、GACに配布 キーを作成し、“snk”ファイルを関連付ける “config”ファイルを利用してバージョンによるリダイレクトも可(“bindingRedirect”属性)


Download ppt "Introduction to C#."

Similar presentations


Ads by Google