1

このフォーラムで質問を検索し、優れたリソースを見つけました。リフレクションの概念を理解するために、私は次のコードを自分で作成しました。

static void Main(String[] args)
    {

        MyClass1 mc1 = new MyClass1();
        Type t = mc1.GetType();
        MethodInfo mInfo = t.GetMethod("method1");
        object[] o=new object[]{2};
        Console.WriteLine(mInfo.Invoke(mc1, o));
        NameSpace2.Class1 c1 = new NameSpace2.Class1();
        Type t2 = c1.GetType();
        MethodInfo[] mI2 = t2.GetMethods();
        object[] o2 = new object[] {2,3};
        foreach (MethodInfo m in mI2)
        {
            Console.WriteLine(m);
        }

        object x = Activator.CreateInstance(t);

        Console.WriteLine(x.GetType());
        Console.Read();

    }

リフレクションを使用すると、実行時にオブジェクトのタイプ、パブリックメソッド、プロパティに関する情報を取得でき、そのタイプのオブジェクトを作成できることも理解しています。しかし、私の要点は、メソッドが入力として必要なパラメーターが何であるかがわからない限り、メソッドを実装することはできず、それらの情報は実行時にのみ利用可能であるということです。それで、反射の重要性は何ですか、それはオブジェクトに関する情報だけですか?

4

3 に答える 3

3

リフレクションが必要な場合、ニーズはコンパイル時ではなく実行時に解決されます。

  • モジュール化が必要なクールなアプリケーションを作成しているとしましょう。開発者にアプリケーションのプラグインを作成させます。作成される可能性のあるすべてのプラグインに対してアプリをコンパイルすることはできません。次に、リフレクションを使用してプラグインのオブジェクトをロード、イントロスペクト、および呼び出す必要があります。

  • 銀行アプリケーション用のミドルウェアを作成しているとしましょう。このミドルウェアは、データベース接続の処理と、そのデータを使用したビジネス ロジックの実行を担当します。使用可能なデータベースごとにミドルウェアをコーディングしてコンパイルできます。または、一度コーディングして、実行時に正しいデータベース ドライバーを有効にして使用することもできます。

  • WebService の WSDL を動的に取得し、プロキシを生成し、プロキシがコンパイルされてメモリにロードされた直後に Web サービスを使用したい場合はどうすればよいでしょうか? コンパイル時にこれを行う方法を考えることができません。

  • さらに良いことに、CodeDOM でコードを生成し、コンパイルして、コンパイル済みのアセンブリを読み込み、コンパイルしたばかりのオブジェクトを使用するとどうなるでしょうか。

いつの日か、リフレクションを使用する必要があります。そうだといい...

于 2012-12-27T12:26:20.660 に答える
1

Adrian Salazarの回答に加えて、私が過去に直面したいくつかの例があります。

  • 自動ラッパー生成。OpenGL/OpenAL を使用するクロスプラットフォーム フレームワークを作成しました。シンプルにするために、デバイスが使用可能になった後に初期化されるデリゲートを使用しました。iOS では、すべてのメソッドを dll-import 属性を持つ extern メソッドとして宣言する必要があります。OpenGL/OpenAL には両方とも多くのメソッドがあるため、デリゲートをコンパイルし、これらのメソッドをすべて宣言する *.cs ファイルを書き込むプログラムを作成しました。今のところ、このラッパーを最新の状態に保つための約 1 週間の骨の折れる作業を安全に行うことができます。
  • プロキシ世代。Flash オブジェクトを処理し、それらのプロパティを PropertyInspector に表示し、オブジェクトのメソッドを呼び出す必要があるアプリケーションを一度書きました。これを行うには、IL ジェネレーターを書き、リフレクションを使用してプロパティを反映し、メソッドを呼び出します。
  • 最も一般的なサンプルは次のとおりです。データのロードと保存。このタスクは、主にリフレクションを使用して行われます。2012 年の半ばに、XAML で行うようにオブジェクトを初期化し、このオブジェクトを XML に再度保存できる xml-reader/writer を作成しました。リフレクションを使用していない場合、オブジェクトの初期化とそれらの XML への再書き込みは、多くの作業を引き起こすタスクです。

ご覧のとおり、リフレクションが本当に役立つことを証明する多くの例があります。過去 8 年間にリフレクションを何度も使用したので、使用回数を数えることさえできません。

于 2012-12-27T12:47:01.337 に答える
0

あなたの暗黙の質問に話すこと。

しかし、私が言いたいのは、メソッドが入力として必要とするパラメーターが何であるかがわからない限り、メソッドを実装することはできず、それらの情報は実行時にしか利用できないということです。

簡単な例を挙げてみましょう。パラメーターを必要とするクラスでメソッドをインスタンス化する必要があり、ファシリテーターになります (つまり、クラスを作成してメソッドを起動しますが、それについては何も知りません)。

public class Foo
{
    public Foo() { }

    public void FooMethod(string parm) { }
}

public class Facilitator
{
    public void RaiseAction(string type, string action, params object[] parm)
    {
        var o = Activator.CreateInstance("MyAssembly", type);
        var methodInfo = o.GetType().GetMethod(action);
        if (methodInfo == null) { return; }
        methodInfo.Invoke(o, parm);
    }
}

さて、上記の例では、何も知らなかったオブジェクトのメソッドにパラメータを渡しただけです。

では、Reflection で可能な他のいくつかのことを調べてみましょう。ちょっと想像してみてくださいprivate- 一般的には悪い考えですが - 必要に応じてメンバーに到達する必要があり、デバッグハッキングのために行うこともあります。決定を下すために、実行時にアクセスできないフラグが必要だったことはありませんか? デバッガーでフラグを見ましたが、オブジェクト階層に埋め込まれており、起動するprivate必要があります! 何が悪いの?マイクロソフトは、今後のリリースで何らかの形で公開すると述べていますが、今すぐドアを出る必要があり、このフラグが必要です! または、この方法が必要な場合もあります。

この例を考えてみましょう(oプライベートなものから何かが必要なオブジェクトはどこにありますか):

var propertyInfo = o.GetType().GetProperty("SomePublicProperty");
if (propertyInfo == null) { return; }
var myFirstPrivateMember = propertyInfo.PropertyType.GetField("_somePrivateField", BindingFlags.Instance | BindingFlags.NonPublic);

おお、最初のprivateメンバーを獲得しました。フィールドも同様です。

データベースから UX に至るまで、完全に動的な多数のアプリケーションを構築してきたので、リフレクションは私にとって大切なものです。そのようなアプリケーションを構築するとき、あなたは何についてもよく知りません - あなたはそれを設定しませんでした - しかし、リフレクションの柔軟性のおかげで、仕事を成し遂げるために必要なことや必要なことは何でもできますInvokeGet

他のものと同じように、これらはリフレクションの非常に単純な例ですが、リフレクションの力と、それがなぜ役立つのかをよく理解していただければ幸いです。あなたの世界が非常に静的であるほとんどの日常的なアプリケーションでは、おそらくそれを使用することはありませんが、少し分岐してより動的になると、それが必要になります.

于 2012-12-27T12:25:43.023 に答える