2010-09-16 2 views
2

Есть ли способ использовать методы расширения для класса, динамически созданного с помощью Relection.Emit? Например:Использование методов расширения со сборками времени выполнения

class somewhere 
{ 
    somewhere() 
    { 
     // define the type here using ReflectionEmit, etc. 
     Type tableType = CreateTableType(...table parameters...); 

     var table = Activator.CreateInstance(tableType); 
     table.Shuffle(); 
    } 
} 

//... elsewhere 
public class static TableTypeExtensions 
{ 
     public static Table Shuffle(this Table t) 
     { 
      ... 
     } 
} 

Но у меня нет класса по названию «Таблица», только Тип tableType доступен.
Есть ли способ обойти это?

ответ

3

Определите общий базовый класс для вашего TableType и определите для него метод расширения. Таким образом, ваш метод расширения должен быть доступен и для производных классов.

+0

Я предпочитаю предложение интерфейса, но это тоже хорошо. –

+0

Согласовано. Упрощенный. –

+0

Я использовал это в своем последнем коде. Для меня больше смысла добавлять функциональность к классу, чем к интерфейсу. –

4

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

+0

@downvoter Почему downvote? Это хорошее и общее решение вопроса OP: «Есть ли способ использовать методы расширения для класса, который был динамически создан с помощью Relection.Emit?». –

3

Давайте посмотрим, что вы просите.

Вы спрашиваете, как получить метод расширения для работы с экземпляром объекта.

Очевидно, что для работы это должно быть Table, иначе ваш вопрос не имеет смысла.

Так что бросайте его Table:

var table = (Table)Activator.CreateInstance(tableType); 

и вы можете назвать ваш метод расширения просто отлично.

+0

Вам не нужно бросать его в базовый класс. Метод расширения также доступен для производных типов. –

+3

Если он строит тип через отражение, он не имеет производного типа как «тип» как таковой, а только экземпляр объекта. И результат Activator.CreateInstance имеет тип 'object'. Приведение - это просто, чтобы заставить компилятор распознать правильный тип. –

+0

Я думаю, что мой пример слишком упрощен. На самом деле у меня нет класса Table в любом месте. Тип tableType определяется как recordType = moduleBuilder.DefineType ("name"); tableType = typeof (BindingList <>). MakeGenericType (recordType); –

0

В коде somewhere у вас есть ссылка на тип Table? Если это так, вы можете:

Type tableType = CreateTableType(...table parameters...); 

var table = Activator.CreateInstance(tableType) as Table; 
table.Shuffle(); 
+0

Вы должны использовать бросок, а не 'как'. – Timwi

Смежные вопросы