Browse DevX
Sign up for e-mail newsletters from DevX


Get Drunk on the Power of Reflection.Emit : Page 2

With Reflection.Emit, you can add dynamic typing to your C# applications and enter a strange new world.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Mass Producing Your Dynamic Types
The next step is to figure out how to instantiate your dynamic type. The simplest method (shown above) is to use reflection, using Activator.CreateInstance(). But, there are a couple of problems with the reflection-based approach. First, there's no obvious way to instantiate an object with a non-default set of parameters. Also, you might be wary of the poor performance that's often associated with reflection (but more on that later).

An alternative to the reflection-based approach is to use the Prototype pattern. The idea here is to create new objects by copying a prototypical instance. The good news about using the prototype pattern is that it doesn't require any reflection at all. Here's the implementation:

class HydratingCopier { readonly BinaryFormatter b = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); public HydratingCopier (object toSerialize) { factoryType= toSerialize.GetType(); b.Serialize (stream, toSerialize); } public object New() { stream.Position=0; return b.Deserialize(stream); } }

The advantage of this pattern is that you only have to use Activator.CreateInstance a single time—to create your initial prototype. After that, you can create new instances by "hydrating" a serialized copy—that is, populating the properties of the serialized copy with values.

The bad news is that this particular prototype implementation uses serialization. This puts a constraint on the target class: It must be serializable.

Strategy #2: Building Dynamic Adapters
If dynamically subclassing an object seems way too easy, you've got good instincts. It turns out that subclassing a type to add an interface has at least three limitations:

  • Methods of the base class must be explicitly marked as virtual.
  • The base class has to be a class, and not a struct.
  • The target class can't be sealed.
So what's the alternative to subclassing? One option is to dynamically build an object adapter that wraps the target class, and implements the specified interface. My approach here was inspired by a really cool CodeProject article by Rüdiger Klaehn called Autocaster.

Before you get into building more dynamic classes, take a look at the non-dynamic object adapter. The ShootableCameraAdapter wraps a Camera object to make it compatible with the IShootable interface:

public class ShootableCameraAdapter: IShootable { private Camera wrappedCamera; public ShootableCameraAdapter (Camera camera) { this.wrappedCamera = camera; } public void Shoot() { wrappedCamera.Shoot(); } }

Listing 1 looks convoluted, but it's not doing any rocket science. Really, it's just building a new type that implements the specified interface, and looping through the interface methods, adding a call to the wrapped object for each one. The only downside to this approach is that it doesn't pass the substitution test. That is, you can't substitute an instance of the wrapper type for an instance of the base type because they don't participate in an inheritance relationship.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date