.NETリフレクションを使用するプライベートメソッド。どうして?
-
06-07-2019 - |
質問
以前はパブリックメソッドで何度もリフレクションを使用していましたが、プライベートメソッドも呼び出すことができることに気付きませんでした。 プライベートメンバーの反射 を参照してください。
そもそもなぜそれが許可されているのですか? 「プライベート」のルールを破るのではないでしょうか。 「プライベート」ですか?
解決
private
は、まさに言語仕様の一部にすぎません。 C#言語、およびVisual Basic言語またはその他の適切な.NET言語( CIL 、すべての.NET言語がコンパイルするもの) private
(または、派生クラス内にない場合は protected
)メンバー< strong>言語で。ただし、言語が private
または protected
メンバーへのパブリックアクセスをサポートしていないからといって、基盤となるフレームワークがそれらのメンバー。
これは、通常、リフレクションなどの回避策を使用して private
または protected
のメンバーにアクセスまたは変更することはできませんが、とにかくフレームワークで許可されています。一般に、 private
または protected
のメンバーにアクセスするには、非常に正当な理由が必要です。たとえば、そのような理由の1つは、オブジェクトを適切にシリアル化するためにオブジェクトの内部状態を調べる必要があるシリアライザーを実装することです。そのようなことをしていない場合は、プログラム内でリフレクションを使用する必要がないように、内部で突っついているクラスを再実装することを真に検討する必要があります。
他のヒント
これは、コードが完全な信頼の下で(または関連する権限で)実行されている場合にのみ許可されます。そうでない場合、 MethodAccessException
がスローされます。
フレームワークは、アクセスを適切に制限することができます。完全な信頼の下で実行しているとき、または特定のアクセス許可があるときは、アクセスを制限しません。いつの詳細については、&quot;リフレクションのセキュリティに関する考慮事項を参照してください。 'これを行うことができます。
はい、ルールを破ります。誰かがこれをした場合、レビュー中にコードを渡すことはほとんどありませんでした。
リフレクションを使用したメソッドの呼び出しはslllloooowであり、タイプセーフではありません。基になるクラスにプライベートメソッドが再作成されている場合、簡単に壊れます。
要するに、私は同意します、それは悪い考えです!
これは、フレームワークから得られる高度な機能です。実動コードでメソッドを呼び出すために使用することは非常にまれであり、メンバーが隠れているという利点を損ないます。
便利な場所がいくつかあります:
- レガシーコードのテスト-たとえば、レガシーコードを使用しており、単体テストでカバーしたいとします。コードの変更が許可されておらず、プライベートメソッドを呼び出す機能の一部をテストしたい場合は便利です。
- 製品コードのハッキング-あるシナリオではプライベートクリーンアップが行われなかったサードパーティコントロールのバグに一度遭遇しました。 private invokeを使用すると、回避できます。
この機能を提供するフレームワークには何の問題もありませんが、必須ではない場所での使用は間違っています。
反射は.NETの強力な機能ですが、欠点もあります。
長所:
-
Reflectionでは、少なくとも ReflectionPermission セキュリティがあれば、すべてのメンバー(プライベートおよび保護を含む)へのアクセスが許可されます。 (この許可は、アプリケーションがインターネットからではなく、同じドライブからリフレクションされたアセンブリにアクセスするときに取得できます。)
-
まれに、リフレクションがタスクを実行する唯一の方法です。
短所:
-
反射はセキュリティを破壊します(アセンブリの逆コンパイルも同様です)。アプリケーションのコードとデータの完全なセキュリティを確保するには、PrivateまたはProtectedキーワードに依存するだけでなく、暗号化を使用する必要があります。
-
反射は、静的参照(メソッドを呼び出す通常の方法)よりもはるかに遅く、多くのリソースを消費します。このため、問題を解決する唯一の方法でない限り、リフレクションを避ける必要があります。
反射が問題を解決する唯一の方法である場合の例は次のとおりです。
-
アプリケーションがコードを動的にコンパイルするとします(実行時にユーザーが提供する関数をプロットするときなど)。そのような場合、アセンブリと型をロードする唯一の方法はリフレクションを使用することです。
-
オブジェクトのクローンを作成します。プライベートフィールドにアクセスするには、リフレクションを使用する必要があります。
これが役立つことを願っています。 フランチェスコ・バレナ氏の美しい本 『Microsoft Visual Basic 2005のプログラミング:言語』に感謝します。