7

Is it possible to dynamically compose a class from the methods contained in other Classes?

For instance. Class A, B and C have public methods named such that they can be identified easily. They need to be extracted and added to Class D. Class D, which then contains all of the implementation logic can be passed further into a system which only accepts a single instance of Class D and dynamically binds these methods to other functions.

To be clear, this is not inheritance I'm looking for. I'm literally stating that methods with different names need to be stuffed into one class. The system I pass it into understands these naming conventions and dynamically binds them (it's a black box to me).

I am going down the path of extracting the methods from A, B, and C, dynamically combining them with the source of Class D in memory and compiling them into a new Class D and then creating an instance of D and passing it forward.

public class A{  public void EXPORT_A_DoSomething(){} }
public class B{  public void EXPORT_B_DoSomethingElse(){}}
public class C{  public void EXPORT_C_DoAnything(){}}
 //should become
public class D{ 
          public void EXPORT_A_DoSomething(){} 
          public void EXPORT_B_DoSomethingElse(){}
          public void EXPORT_C_DoAnything(){}
}

Is there a way to extract the MethodInfos from class A, B and C and somehow directly attach them to Class D? If so how?

4

5 に答える 5

2

C# Class compilerの使用を検討します。私が覚えている限りでは、文字列内のコードを作成でき、出力としてアセンブリを取得できます。これにより、リフレクションを通じてメソッドを呼び出すことができます。

指定した MSDN リンクに例がありますが、プロジェクトが見つかったら、ここでモックを作成します。

于 2013-03-18T15:02:59.773 に答える
1

メソッドだけをエクスポートすることはできません。メソッドは、それらが含まれるクラスから実際に分離することはできません (継承されたものを含むすべてのメンバー フィールド/プロパティへのアクセスが必要です)。

あなたができる唯一のことは、インターフェイスの実装を発行することだと思います。(あなたが必要としているものではないと言っても、それらのオブジェクトのプライベート状態を必要とする方法はわかりません)

必要なメソッドのみを含む単一のインターフェースを作成し、各タイプのオブジェクトのインスタンスを含むそれをサポートするクラスを提供できます。

public class A{  public void DoSomething(){} }
public class B{  public void DoSomethingElse(){}}
public class C{  public void DoAnything(){}}

public interface ID 
{ 
    void A_DoSomething(); 
    void B_DoSomethingElse(); 
    void C_DoAnything(); 
}

public class D : ID 
{ 
    private A a;
    private B b;
    private C c;

    public D(A a,B b, C c) { this.a=a;this.b=b;this.c=c; }

    public void A_DoSomething(){ a.DoSomething();} 
    public void B_DoSomethingElse(){ b.DoSomethingElse();}
    public void C_DoAnything(){ c.DoSomething();
}

これを動的に生成する必要がある場合は、Reflection.Emit を調べてください。新しいアセンブリを作成し、それを AppDomain に動的にロードする方法については、ビジネスになるでしょう。できれば避けたいと思います。

于 2013-03-18T15:37:44.063 に答える
0

実際には、「Mixins」と呼ばれるものとプロキシジェネレータを使用して可能になるはずです。Castle.DynamicProxyのチュートリアルを見てください:Mixins

于 2013-03-18T15:25:30.367 に答える
0

もう 1 つの解決策は、関数のクラス get および set アクセサーをインターフェイスとして定義し、関心のある関数を宣言することです。

interface iA
{
    public int a { get; set; }
}
interface iB
{
    public int b { get; set; }
}
interface iAB : iA, iB
{
}
class MyClass : iA, iB
{
    public int b { get; set; }
    public int a { get; set; }
}
static class MyClassExtender
{
    static public int Foo(this iAB ab)
    {
        int c = ab.a + ab.b;
        ab.a = c;
        return c;
    }
    static public int FooA(this iA a)
    {
        int c = ab.a + 1;
        ab.a = c;
        return c;
    }
    static public int FooB(this iB b)
    {
        int c = ab.b + 1;
        ab.a = c;
        return c;
    }

}

これで、"MyClass" は Foo、FooA、および FooB をパブリック メソッドとして使用できるようになりました。

于 2013-03-18T15:21:39.633 に答える
-1

他のクラスのメソッドを指すDクラスのデリゲートのハッシュまたはリストを使用することを単に検討しましたか?または、動的オブジェクト(google ExpandoObject)を使用します。

于 2013-03-18T15:14:28.203 に答える