私は、Windowsフォームコントロールを処理するC#コードの一部に取り組んでいます。これは小さな例です。いくつかのコントロールの境界矩形(画面座標)を取得するための小さなラッパーです。
public class GUIObject {
protected Control m_control;
// [..]
public virtual Rectangle Bounds {
get {
Rectangle r = m_control.Bounds;
if ( m_control.Parent != null ) {
return m_control.Parent.RectangleToScreen( r );
}
return r;
}
}
}
このコードは、顧客のアプリケーションにロードされる「プラグイン」として配布されるライブラリにコンパイルされます。ただし、一部の顧客は、私のプラグインがリンクされているものとは異なるバージョンのWindowsフォームをアプリケーションで使用していることが判明しました。私の計画は、上記のコードをレイトバウンドにすることでこれに取り組むことでした。これにより、現在のアプリケーションドメインにロードされているWindowsフォームのバージョンに関係なく機能するようになります。.NET 4では、dynamic
キーワードを使用できましたが、残念ながら、このコードは.NET3アプリケーションでも機能するはずです。したがって、私はリフレクションAPIの使用を開始し、リフレクションAPIの使用を少し良くする小さなヘルパーオブジェクトを導入しました。
public class LateBoundObject {
private Object m_o;
// [..]
public Object GetProperty( String name ) {
PropertyInfo pi = m_o.GetType().GetProperty( name );
return pi == null ? null
: pi.GetValue( m_o, null );
}
public Object InvokeMethod( String name, Object[] args ) {
MethodInfo mi = m_o.GetType().GetMethod( name );
return mi == null ? null
: mi.Invoke( m_o, args );
}
}
public class GUIObject {
protected LateBoundObject m_control;
// [..]
public virtual Rectangle Bounds {
get {
Object r = m_control.GetProperty( "Bounds" );
if ( r == null) {
return new Rectangle();
}
Object parent = m_control.GetProperty( "Parent" );
if ( parent != null ) {
LateBoundObject po = new LateBoundObject( parent );
r = po.InvokeMethod( "RectangleToScreen",
new Object[] { r } );
}
return (Rectangle)r;
}
}
}
あまりきれいではありません。発信者側では多くのキャストが必要であり、遅かれ早かれオーバーロードされたメソッドやプロパティにも対処する必要があると思います。理想的には、ラッパーオブジェクトを使用すると、元のコードをほとんど同じに保つことができます。
したがって、LateBoundObject
ラッパークラスの修正を開始する前に、リフレクションAPIを使用してC#コードをレイトバウンドにした経験がある人はいますか?もしそうなら、生のリフレクションAPIを使用する苦痛を最小限に抑えるために、どのようにアプローチしましたか?また、のラインに沿ってラッパークラスを使用しましたか、LateBoundObject
それともまったく異なるルートを使用しましたか?元のコードに関する限り、最も侵襲性の低い方法を探しています。