views:

63

answers:

4

Is there any way to use extension methods on a class that has been dynamically created using Relection.Emit? For example:

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

But I don't have the class by name "Table", only Type tableType available.
Is there any way around this?
Thanks

+4  A: 

Make the dynamic class implement an interface (an empty one if you want), add extensions to the interface.

BioBuckyBall
@downvoter Why the downvote? It's a good and common solution to the OP's question "Is there any way to use extension methods on a class that has been dynamically created using Relection.Emit?".
BioBuckyBall
+3  A: 

Define a common base class for your TableType and define the extension method on that. This way your extension method should be available for the derived classes as well.

Rune Grimstad
I prefer the interface suggestion, but this is good too.
Marc Gravell
Agreed. Upvoted it.
Rune Grimstad
I used this in my final code. It makes more sense to me to add functionality to a class than to an interface.
Max Yaffe
+3  A: 

Let's look at what you're asking.

You're asking how to get the extension method to operate on your object instance.

Obviously, for this to work, it has to be a Table, otherwise your question makes no sense.

So just cast it to Table:

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

and you can call your extension method just fine.

Lasse V. Karlsen
You don't have to cast it to it's base class. The extension method is available on the derived types as well.
Rune Grimstad
If he's constructing the type through reflection, he doesn't have the derived type as a "type" per se, only the object instance. And the result of Activator.CreateInstance is of type `object`. The cast is just to get the compiler to recognize the correct type.
Lasse V. Karlsen
I think my sample is too simplistic. I don't actually have a Table class defined anywhere. The tableType is defined by recordType = moduleBuilder.DefineType("name");tableType = typeof(BindingList<>).MakeGenericType(recordType);
Max Yaffe
@Lasse: Good point. I read your answer as saying he needed to cast to Table to get the extension methods, my bad :-)
Rune Grimstad
If the question has been answered, you should accept the answer that answered it.
Lasse V. Karlsen
Thanks for your help. I've got running code now but still testing for efficiency. Actually the final code will use parts of several answers. Too bad I can't check more than one. I'll post it when done.
Max Yaffe
A: 

In your somewhere code do you have reference to the type Table? If so you can:

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

 var table = Activator.CreateInstance(tableType) as Table;
 table.Shuffle();
dkackman
You should use a cast, not `as`.
Timwi