24

最近、私はC ++について同僚と話していて、クラスフィールドの名前の文字列を取得して、その名前のフィールドを抽出する方法がないことを嘆きました。言い換えれば、それは反射を欠いています。彼は私に困惑した表情を見せ、いつ誰かがそのようなことをする必要があるのか​​と尋ねました。

頭のてっぺんから、「ねえ、今すぐやる必要がある」以外は、彼に良い答えはありませんでした。そこで私は座って、さまざまな言語でのリフレクションで実際に行ったことのいくつかのリストを思いつきました。残念ながら、私の例のほとんどはPythonでのWebプログラミングからのものであり、ここの人々がもっと多くの例を持っていることを望んでいました。これが私が思いついたリストです:


  1. x = "Hello World!"のような行を含む構成ファイルがあるとします。
    y = 5.0
    は、あるオブジェクトのフィールドをconfigそのファイルの値と等しく設定します。(これは、C ++で実行できることを望んでいましたが、実際には実行できませんでした。)

  2. オブジェクトのリストを並べ替えるときは、構成ファイルまたはWeb要求からの属性の名前を指定して、任意の属性に基づいて並べ替えます。

  3. ネットワークプロトコルを使用するソフトウェアを作成する場合、リフレクションを使用すると、そのプロトコルの文字列値に基づいてメソッドを呼び出すことができます。たとえば
    !some_command arg1 arg2
    、メソッド呼び出しに変換して、actions.some_command(arg1, arg2)その関数がIRCチャネルに返すものをすべて出力するIRCボットを作成しました。

  4. Pythonの__getattr__関数(Ruby / Smalltalkのmethod_missingのようなもの)を使用するとき、私はlate_totalなどの統計がたくさんあるクラスで作業していました。すべての統計について、_percentを追加して、カウントしている合計値のパーセンテージとしてその統計を取得できるようにしたかった(たとえば、stats.late_total_percent)。リフレクションはこれを非常に簡単にしました。

それで、ここの誰かが、振り返りが役に立ったときの彼ら自身のプログラミング経験からの例を与えることができますか?次回、同僚から「そんなことをしたい」と聞かれたときは、もっと準備をしていきたいと思います。

4

9 に答える 9

21

リフレクションの次の使用法をリストできます。

  • 遅延バインディング
  • セキュリティ(セキュリティ上の理由からコードをイントロスペクトする)
  • コード分​​析
  • 動的型付け(ダックタイピングはリフレクションなしでは不可能です)
  • メタプログラミング

私の個人的な経験からの反射のいくつかの実際の使用法:

  • リフレクションに基づいて開発されたプラグインシステム
  • アスペクト指向プログラミングモデルを使用
  • 静的コード分析を実行しました
  • さまざまな依存性注入フレームワークを使用
  • ..。

反射は良いことです:)

于 2008-09-08T14:08:02.733 に答える
4

リフレクションを使用して、例外やロギングなどの現在のメソッド情報を取得しました。

string src = MethodInfo.GetCurrentMethod().ToString();
string msg = "Big Mistake";
Exception newEx = new Exception(msg, ex);
newEx.Source = src;

それ以外の

string src = "MyMethod";
string msg = "Big MistakeA";
Exception newEx = new Exception(msg, ex);
newEx.Source = src;

コピー/貼り付けの継承とコード生成が簡単になります。

于 2008-09-08T14:01:04.763 に答える
3

私は今、XMLのストリームがネットワークを介して入ってくる状況にあり、ストリーム内の要素からそれ自体を取り込むエンティティオブジェクトをインスタンス化する必要があります。リフレクションを使用して、巨大なメンテナンスの悪夢の条件ステートメントを作成するよりも、どのエンティティオブジェクトがどのXML要素を処理できるかを把握する方が簡単です。XMLスキーマと、オブジェクトの構造と名前の付け方には明らかに依存関係がありますが、両方を制御するので、大きな問題にはなりません。

于 2008-09-08T14:06:31.567 に答える
2

実行時までタイプがわからないオブジェクトを動的にインスタンス化して操作したい場合がよくあります。たとえば、ORマッパーやプラグインアーキテクチャを使用します。ロギングライブラリを作成し、例外のタイプとプロパティを動的に調べたい場合は、モックフレームワークがこれを使用します。

もう少し長く考えると、おそらくもっと多くの例を思いつくことができます。

于 2008-09-08T13:52:27.560 に答える
2

入力データ (xml など) がオブジェクト インスタンスに簡単にマップできる複雑な構造を持っている場合、またはインスタンス間に何らかの "is a" 関係が必要な場合、リフレクションは非常に便利です。

Java ではリフレクションが比較的簡単なので、小さな固定キー セットを持つ単純なデータ (キーと値のマップ) にリフレクションを使用することがあります。キーが有効かどうかを判断するのは簡単です (クラスにセッター setKey(String data) がある場合)。一方で、(テキスト) 入力データの型を変更し、変換を非表示にすることができます (単純なキャストなど)。 getKey()) で int に変換されるため、アプリケーションの残りの部分は正しく型付けされたデータに依存できます。1 つのオブジェクトのキーと値のペアの型が変更された場合 (例: int から float へ)、データ オブジェクトとそのユーザーで変更するだけでよく、パーサーもチェックする必要はありません。 . パフォーマンスが問題になる場合、これは賢明なアプローチではないかもしれません...

于 2008-09-08T14:46:53.967 に答える
1

コーディネーターを書く。Twistedは、Pythonのリフレクティブ機能を使用して、XML-RPCおよびSOAP呼び出しをディスパッチします。RMIは、ディスパッチにJavaのリフレクションAPIを使用します。

コマンドライン解析。渡されたコマンドラインパラメータに基づいて構成オブジェクトを構築します。

単体テストを作成するときは、リフレクションを使用すると便利ですが、ほとんどの場合、これを使用してアクセス修飾子(Java)をバイパスしました。

于 2008-09-08T13:52:58.683 に答える
1

フレームワークまたはアクセスしたいサードパーティのライブラリに内部メソッドまたはプライベートメソッドがある場合は、C#でリフレクションを使用しました。

(免責事項:プライベートメソッドと内部メソッドは後のバージョンで変更される可能性があるため、必ずしもベストプラクティスではありません。ただし、必要な場合は機能しました。)

于 2008-09-08T13:55:13.933 に答える
1

静的に型付けされた言語では、「動的」なことをする必要があるときはいつでもリフレクションを使用したいと思うでしょう。これは、ツールの目的(オブジェクトのメンバーのスキャン)に役立ちます。Javaでは、JMXおよび動的プロキシでかなり使用されます。そして、それが本当に唯一の方法である1回限りのケースがたくさんあります(コンパイラーが実行できないことを実行する必要がある場合はほとんどいつでも)。

于 2008-09-08T13:55:31.563 に答える
1

私は通常、デバッグにリフレクションを使用します。リフレクションは、さまざまな印刷ステートメントよりも、システム内のオブジェクトをより簡単かつ正確に表示できます。ファーストクラスの関数を持つ多くの言語では、特別なコードを記述せずにオブジェクトの関数を呼び出すこともできます。

ただし、やりたいことを行う方法があります。ハッシュテーブルを使用します。フィールド名に対してキー設定されたフィールドを格納します。

本当に必要な場合は、標準のGet / Set関数を作成するか、その場でそれを実行するマクロを作成できます。#define GetX() Get("X")ある種のこと。

そのようにして、独自の不完全な反射を実装することもできます。

上級ユーザーの場合、コードをコンパイルできれば、デバッグ出力の生成を有効にして、それを使用してリフレクションを実行できる可能性があります。

于 2008-09-21T01:18:28.317 に答える