Динамически создать класс В C#

можно ли динамически создать класс из методов, содержащихся в других классах?

например. У классов A, B и C есть открытые методы, названные так, что их можно легко идентифицировать. Они должны быть извлечены и добавлены в класс D. класс D, который затем содержит всю логику реализации, может быть передан далее в систему, которая принимает только один экземпляр класса D и динамически связывает эти методы с другими функциями.

чтобы было понятно, это не наследство, которое я ищу. Я буквально заявляю, что методы с разными именами должны быть заполнены в один класс. Система, в которую я ее передаю, понимает эти соглашения об именах и динамически связывает их (для меня это черный ящик).

Я иду по пути извлечения методов из A, B и C, динамически объединяя их с источником класса D в памяти и компилируя их в новый класс D, а затем создавая экземпляр D и передавая его вперед.

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(){}
}

есть ли способ извлечь MethodInfos из класса A, B и C и каким-то образом напрямую присоединить их к классу D? Если да, то как?

5 ответов


Я бы рассмотрел возможность использования компилятор класса C#. Из того, что я помню, вы можете построить код, который находится в строке, и вы можете получить сборку в качестве вывода. Это затем позволяет вызывать методы через отражение.

есть пример по ссылке MSDN, которую я указал, но я буду макет один здесь, как только я найду свой проект.


вы не сможете экспортировать только методы. Методы не могут быть отделены от класса, в котором они находятся. (им нужен доступ ко всем полям-членам/properites, включая унаследованные).

Я думаю, что единственное, что вы можете сделать, это испустить реализацию интерфейса. (хотя вы говорите, что это не то, что вам нужно, я не вижу способа обойти необходимость частного состояния для этих объектов)

вы можете сделать единый интерфейс, который содержит только методы, которые вы необходимо, и предоставить класс, который поддерживает его, который содержит экземпляр каждого типа объекта.

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();
}

Если вам нужно генерировать это динамически, посмотрите на отражение.Испускают. Это будет некоторое дело о том, как вы должны создать новую сборку, а затем динамически загрузить ее в AppDomain. Я постараюсь избежать этого, если сможешь.


на самом деле это должно быть возможно, используя что-то под названием "Mixins" и генераторы прокси. Взгляните на замок.Учебник DynamicProxy:Mixins


другое решение-определить класс get и установить методы доступа для функции в качестве интерфейса и объявить функции, которые вас интересуют.

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 в качестве общедоступных методов.


вы рассматривали просто использование хэша или списка делегатов в вашем классе D, которые указывают на методы в других классах? Кроме того, используйте динамический объект (google ExpandoObject).