2009-06-24 21 views
15

私はreflectionのすべての投稿に行きましたが、私の質問に対する答えが見つかりませんでした。反射はどのような問題を解決しますか?

.NETリフレクションが登場する前のプログラミングの世界の問題点とその解決方法について教えてください。

例を挙げて説明してください。

+2

@Praveen - これはかなり広い質問です。あなたはもっと具体的になりますか? –

+0

現時点では本当の質問ではありません。答えることは不可能です。おそらく、あなたが決定しようとしているもので展開した場合。 – Richard

+0

この宿題はありますか? – erikkallen

答えて

14

.NETリフレクションは革命的ではないことを述べる必要があります。概念は他のフレームワークの中にあります。 .NETで

反射が2面あります

反射/イントロスペクションAPIのいくつかの種類がなけれ型情報

の調査を、それがシリアライズのようなものを行うことが非常に困難となります。これを実行時に(プロパティ/フィールド/などを調べることによって)提供するのではなく、代わりにコード生成、つまりそれぞれの型を直列化する方法を明示的に示すコードが必要なことがよくあります。あなたが双子を持たないものを連載したいのであれば、退屈で苦しいです。

同様に、プロパティなどに関する追加のメタデータを保存する場所がないため、多くの追加コードや外部設定ファイルが必要になります。フレンドリ名とプロパティ(属性を介して)を関連付けることができるという単純なことは、UIコードにとって大きな勝利です。

メタプログラミング

NETの反射はまた、いくつかの特定のシナリオに非常に強力であり、実行時に型(など)を作成するためのメカニズムを提供します。選択肢は以下のとおりです。

  • は、基本的に、実行時にパーサ/ロジックツリーを実行している(というよりも、実行可能コードに実行時にロジックをコンパイル) -
  • はるかに遅く、まだ多くのコード生成 - イェーイ!
9

私は.NETでのリフレクションの必要性を理解するために、.NETの前に戻る必要があります。結局のところ、JavaやC#のような現代の言語は履歴BF(反映前)を持っていません。

C++はおそらくC#とJavaに最も大きな影響を与えています。しかし、C++はもともとリフレクションを持っておらず、コードなしでコード化してしまいました。時には私たちはポインタを無効にし、私たちが望むどんなタイプにでもそれを強制するためにキャストを使用しました。ここでの問題は、キャストがひどい結果で失敗ということでした。

double CalculateSize(void* rectangle) { 
    return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight()); 
} 

は今、あなたが最初の場所でこの問題に自分でコード化されていない理由の引数がたくさんあります。しかし、問題は、我々がジェネリックを持っていなかったときのC#と.NET 1.1と大差ありません:

しかし
Hashtable shapes = new Hashtable(); 
.... 
double CalculateSize(object shape) { 
    return ((Rect)shape).Width * ((Rect)shape).Height; 
} 

、C#の例が、それは例外ではなく、潜在的なコアダンプでそうする失敗します。

C++にリフレクションが追加されたとき(ランタイムIDまたはRTTIとして知られていました)、熱心に議論されました。

Declared the support unnecessary 
Declared the new style inherently evil ("against the spirit of C++") 
Deemed it too expensive 
Thought it too complicated and confusing 
Saw it as the beginning of an avalanche of new features 

しかし、それは、私たちは、オブジェクトの種類を照会することができ、またはの機能でした:Stroustrup氏の本のデザインと進化C++のでは、彼は何人かの人々に、RTTIに対して次の の引数を示していますオブジェクト。たとえば、(C#を使用)

Hashtable shapes = new Hashtable(); 
.... 
double CalculateSize(object shape) { 
    if(shape is Rect) { 
     return ((Rect)shape).Width * ((Rect)shape).Height; 
    } 
    else if(shape is Circle) { 
     return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI; 
    } 
} 

もちろん、この例は決して実行する必要はありません。だから、

、私はそれには、必要に応じてきた現実の世界の状況:

  • は、共有メモリからオブジェクトへのアクセス、私が持っているすべては、ポインタであり、私はそれで何をすべきかを決定する必要があります。
  • アセンブリを動的に読み込み、すべてのアセンブリをロードするNUnitについて考え、リフレクションを使用してどのクラスがテストフィクスチャであるかを判断します。
  • ハッシュテーブルにオブジェクトの混在した袋があり、それらを列挙子で別々に処理したい。
  • 他の多く...

だから、私はリフレクションを主張する限り行くだろうが前に行うことができませんでした何かをする能力が有効になっていません。しかし、いくつかの種類の問題をコード化しやすくし、読者にはより明確にし、書くことは短くします。

もちろん私の意見では間違っています。

1

私は一度C++でのフォーマットの非技術的なユーザーによって変更することができ、テキストファイル内のユニットテストを持っていると思った:

MyObj Function args //textfile.txt 

しかし、私は読まする方法を見つけることができませんでしたC++がサポートしていないリフレクションのない文字列によって表されるタイプのオブジェクトインスタンスをコードに作成させることができます。

char *str; //read in some type from a text file say the string is "MyObj" 
str *obj; //cast a pointer as type MyObj 
obj = new str; //create a MyObj 

クラスのメンバーを事前に知らなくてもコピーできる汎用コピー機能を使用することもできます。

0

コードで[Obsolete]や[Serializable]のようなC#属性を使用しているときに役立ちます。 NUnitのようなフレームワークは、クラスのリフレクションを使用し、どのメソッドがテスト、セットアップ、ティアダウンなどであるかを理解するメソッドを含んでいます。

関連する問題