By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,665 Members | 1,363 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,665 IT Pros & Developers. It's quick & easy.

use an enum in an emitted assembly

P: n/a

I want create a method which uses a dynamically enum as the type of one
of its parameters.

I can create the assembly with this code:

AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "EmittedAssembly";

// Create the dynamic assembly.
myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.Save);

// Create a dynamic module.
myModuleBuilder =
myAssemblyBuilder.DefineDynamicModule("EmittedModu le",
"EmittedModule.mod");

// Create a dynamic Enum.
myEnumBuilder = myModuleBuilder.DefineEnum("MyNamespace.MyEnum",
TypeAttributes.Public, typeof(Int32));

FieldBuilder myFieldBuilder1
= myEnumBuilder.DefineLiteral("FieldOne", 1);

FieldBuilder myFieldBuilder2
= myEnumBuilder.DefineLiteral("FieldTwo", 2);

myEnumBuilder.CreateType();
myAssemblyBuilder.Save("Ass1.dll");

But, how do I access this in a method.

I want to do something like

class blah {

myMethod( NyNamespace.MyEnum e)
{
...
}}

But it will not let me use this or

void method(a.GetType("MyNamespace.MyEnum") b)
{
}
How can I use an enum in an emitted assembly to define the input
parameter of a method?
Jul 21 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Hi Moe,

The problem with what you are trying to accomplish is when each part of the
code is defined. The method, and its parameters, are defined at compile
time. However, your enum is defined at run time. The only way to get the
behavior you want is to dynamically build your method at runtime also.

Joe
--
http://www.csharp-station.com

"Moe Green" <mo*@green.vegas> wrote in message
news:33*************@individual.net...

I want create a method which uses a dynamically enum as the type of one of
its parameters.

I can create the assembly with this code:

AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "EmittedAssembly";

// Create the dynamic assembly.
myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.Save);

// Create a dynamic module.
myModuleBuilder =
myAssemblyBuilder.DefineDynamicModule("EmittedModu le",
"EmittedModule.mod");

// Create a dynamic Enum.
myEnumBuilder = myModuleBuilder.DefineEnum("MyNamespace.MyEnum",
TypeAttributes.Public, typeof(Int32));

FieldBuilder myFieldBuilder1
= myEnumBuilder.DefineLiteral("FieldOne", 1);

FieldBuilder myFieldBuilder2
= myEnumBuilder.DefineLiteral("FieldTwo", 2);

myEnumBuilder.CreateType();
myAssemblyBuilder.Save("Ass1.dll");

But, how do I access this in a method.

I want to do something like

class blah {

myMethod( NyNamespace.MyEnum e)
{
...
}}

But it will not let me use this or

void method(a.GetType("MyNamespace.MyEnum") b)
{
}
How can I use an enum in an emitted assembly to define the input parameter
of a method?

Jul 21 '05 #2

P: n/a
Joe Mayo wrote:
Hi Moe,

The problem with what you are trying to accomplish is when each part of the
code is defined. The method, and its parameters, are defined at compile
time. However, your enum is defined at run time. The only way to get the
behavior you want is to dynamically build your method at runtime also.

Joe


Thanks, Joe.

I've seen code showing how to create the Enum dynamically at run time.

But when it comes time to utilize that as the input type of an actual method

void myMethod ( myDynamicEnum mde) { .... }

I can't seem to make heads of tails of it !

For example, I can globally declare the Assembly at the class level, but
if I then try and define a Type using the GetType method of Assembly,
Visual Studio barfs on me.

Can it be done? It seems doable...but I'm just missing some key trick...
Jul 21 '05 #3

P: n/a
Hi Steve,

Here are a few tips:

1. When you instantiate your AssemblyBuilder, you need to change its access
from AssemblyBuilderAccess.Save to AssemblyBuilderAccess.RunAndSave.

2. Get an instance of your enum via the Enum.ToObject() method.

3. Write the code for the method you want to dynamically generate. Then
use ILDASM to see the IL it generates. Use the compiler generated IL to
figure out what opcodes to use in the ILGenerator.Emit calls.

Here's an example of what you need to do:

using System;
using System.Reflection;
using System.Reflection.Emit;

class Test
{
static void Main()
{
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "EmittedAssembly";

AppDomain myAppDomain = AppDomain.CurrentDomain;

// Create the dynamic assembly.
AssemblyBuilder myAssemblyBuilder =
myAppDomain.DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.RunAndSave);

// Create a dynamic module.
ModuleBuilder myModuleBuilder =
myAssemblyBuilder.DefineDynamicModule("EmittedModu le",
"EmittedModule.mod");

// Create a dynamic Enum.
EnumBuilder myEnumBuilder = myModuleBuilder.DefineEnum("MyEnum",
TypeAttributes.Public, typeof(Int32));

FieldBuilder myFieldBuilder1
= myEnumBuilder.DefineLiteral("FieldOne", 1);

FieldBuilder myFieldBuilder2
= myEnumBuilder.DefineLiteral("FieldTwo", 2);

Type myEnumType = myEnumBuilder.CreateType();

object anEnum = Enum.ToObject(myEnumType, 2);

TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("MyType");

MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod(
"MyMethod",
MethodAttributes.Public,
typeof(void),
new Type[] { myEnumType });

ILGenerator myILGenerator = myMethodBuilder.GetILGenerator();
myILGenerator.Emit(OpCodes.Ldarg_1);
myILGenerator.Emit(OpCodes.Box, myEnumType);
MethodInfo myWriteLineMethodInfo =
typeof(Console).GetMethod("WriteLine",new Type[]{typeof(object)});
myILGenerator.Emit(OpCodes.Call, myWriteLineMethodInfo);
myILGenerator.Emit(OpCodes.Ret);

Type myType = myTypeBuilder.CreateType();

object myInstance = Activator.CreateInstance(myType);

MethodInfo myMethod = myType.GetMethod("MyMethod");

myMethod.Invoke(myInstance, new object[] { anEnum });

myAssemblyBuilder.Save("Ass1.dll");

Console.ReadLine();
}
}
Joe
--
http://www.csharp-station.com

"Steve Zissou" <__****************@hocus.pocus> wrote in message
news:mw**************@newsread3.news.pas.earthlink .net...
Joe Mayo wrote:
Hi Moe,

The problem with what you are trying to accomplish is when each part of
the code is defined. The method, and its parameters, are defined at
compile time. However, your enum is defined at run time. The only way
to get the behavior you want is to dynamically build your method at
runtime also.

Joe


Thanks, Joe.

I've seen code showing how to create the Enum dynamically at run time.

But when it comes time to utilize that as the input type of an actual
method

void myMethod ( myDynamicEnum mde) { .... }

I can't seem to make heads of tails of it !

For example, I can globally declare the Assembly at the class level, but
if I then try and define a Type using the GetType method of Assembly,
Visual Studio barfs on me.

Can it be done? It seems doable...but I'm just missing some key trick...

Jul 21 '05 #4

P: n/a

This is very cool stuff, Joe, thanks for your help.

I got the base working now, and I'm going to walk through your code as well.

Reflection is the coolest.

I think I read that Reflection can be performed direct into memory (not
just saving to a file)...is that true? Can I replace a loaded dll with
the new dynamic dll without going through saving to a file and calling?
Joe Mayo wrote:
Hi Steve,

Here are a few tips:

1. When you instantiate your AssemblyBuilder, you need to change its access
from AssemblyBuilderAccess.Save to AssemblyBuilderAccess.RunAndSave.

2. Get an instance of your enum via the Enum.ToObject() method.

3. Write the code for the method you want to dynamically generate. Then
use ILDASM to see the IL it generates. Use the compiler generated IL to
figure out what opcodes to use in the ILGenerator.Emit calls.

Here's an example of what you need to do:

using System;
using System.Reflection;
using System.Reflection.Emit;

class Test
{
static void Main()
{
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "EmittedAssembly";

AppDomain myAppDomain = AppDomain.CurrentDomain;

// Create the dynamic assembly.
AssemblyBuilder myAssemblyBuilder =
myAppDomain.DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.RunAndSave);

// Create a dynamic module.
ModuleBuilder myModuleBuilder =
myAssemblyBuilder.DefineDynamicModule("EmittedModu le",
"EmittedModule.mod");

// Create a dynamic Enum.
EnumBuilder myEnumBuilder = myModuleBuilder.DefineEnum("MyEnum",
TypeAttributes.Public, typeof(Int32));

FieldBuilder myFieldBuilder1
= myEnumBuilder.DefineLiteral("FieldOne", 1);

FieldBuilder myFieldBuilder2
= myEnumBuilder.DefineLiteral("FieldTwo", 2);

Type myEnumType = myEnumBuilder.CreateType();

object anEnum = Enum.ToObject(myEnumType, 2);

TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("MyType");

MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod(
"MyMethod",
MethodAttributes.Public,
typeof(void),
new Type[] { myEnumType });

ILGenerator myILGenerator = myMethodBuilder.GetILGenerator();
myILGenerator.Emit(OpCodes.Ldarg_1);
myILGenerator.Emit(OpCodes.Box, myEnumType);
MethodInfo myWriteLineMethodInfo =
typeof(Console).GetMethod("WriteLine",new Type[]{typeof(object)});
myILGenerator.Emit(OpCodes.Call, myWriteLineMethodInfo);
myILGenerator.Emit(OpCodes.Ret);

Type myType = myTypeBuilder.CreateType();

object myInstance = Activator.CreateInstance(myType);

MethodInfo myMethod = myType.GetMethod("MyMethod");

myMethod.Invoke(myInstance, new object[] { anEnum });

myAssemblyBuilder.Save("Ass1.dll");

Console.ReadLine();
}
}
Joe

Jul 21 '05 #5

P: n/a
Sure, just use AssemblyBuilderAccess.Run when instantiating your
AssemblyBuilder and skip the call to Save().

Joe
--
http://www.csharp-station.com

"Moe Green" <mo*@green.vegas> wrote in message
news:33*************@individual.net...

This is very cool stuff, Joe, thanks for your help.

I got the base working now, and I'm going to walk through your code as
well.

Reflection is the coolest.

I think I read that Reflection can be performed direct into memory (not
just saving to a file)...is that true? Can I replace a loaded dll with
the new dynamic dll without going through saving to a file and calling?
Joe Mayo wrote:
Hi Steve,

Here are a few tips:

1. When you instantiate your AssemblyBuilder, you need to change its
access from AssemblyBuilderAccess.Save to
AssemblyBuilderAccess.RunAndSave.

2. Get an instance of your enum via the Enum.ToObject() method.

3. Write the code for the method you want to dynamically generate. Then
use ILDASM to see the IL it generates. Use the compiler generated IL to
figure out what opcodes to use in the ILGenerator.Emit calls.

Here's an example of what you need to do:

using System;
using System.Reflection;
using System.Reflection.Emit;

class Test
{
static void Main()
{
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "EmittedAssembly";

AppDomain myAppDomain = AppDomain.CurrentDomain;

// Create the dynamic assembly.
AssemblyBuilder myAssemblyBuilder =
myAppDomain.DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.RunAndSave);

// Create a dynamic module.
ModuleBuilder myModuleBuilder =
myAssemblyBuilder.DefineDynamicModule("EmittedModu le",
"EmittedModule.mod");

// Create a dynamic Enum.
EnumBuilder myEnumBuilder = myModuleBuilder.DefineEnum("MyEnum",
TypeAttributes.Public, typeof(Int32));

FieldBuilder myFieldBuilder1
= myEnumBuilder.DefineLiteral("FieldOne", 1);

FieldBuilder myFieldBuilder2
= myEnumBuilder.DefineLiteral("FieldTwo", 2);

Type myEnumType = myEnumBuilder.CreateType();

object anEnum = Enum.ToObject(myEnumType, 2);

TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("MyType");

MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod(
"MyMethod",
MethodAttributes.Public,
typeof(void),
new Type[] { myEnumType });

ILGenerator myILGenerator = myMethodBuilder.GetILGenerator();
myILGenerator.Emit(OpCodes.Ldarg_1);
myILGenerator.Emit(OpCodes.Box, myEnumType);
MethodInfo myWriteLineMethodInfo =
typeof(Console).GetMethod("WriteLine",new Type[]{typeof(object)});
myILGenerator.Emit(OpCodes.Call, myWriteLineMethodInfo);
myILGenerator.Emit(OpCodes.Ret);

Type myType = myTypeBuilder.CreateType();

object myInstance = Activator.CreateInstance(myType);

MethodInfo myMethod = myType.GetMethod("MyMethod");

myMethod.Invoke(myInstance, new object[] { anEnum });

myAssemblyBuilder.Save("Ass1.dll");

Console.ReadLine();
}
}
Joe

Jul 21 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.