title: Dynamically create, and use, an enumeration type
body: <p>I have searched google and have gotten bits and pieces of this puzzle I am trying to create, yet there are still missing pieces that I cannot figure out:</p>
  
  <p>I am trying to create, and fully use, a dynamic Enumeration Type.  </p>
  
  <p>This is what I have and is the basis for this discussion. It is the NON dynamic way of doing things. This is what I am trying to mimic:</p>
  
  <pre><code>// 1) Create the enum and classes
  public enum MyAnimals { Cat, Dog, Pig };
  
  public abstract class Animal { internal MyAnimals _myType; 
                                 public MyAnimals myType {get{return _myType;}} }
  public class Cat : Animal { public Cat(){_myType = MyAnimals.Cat;} }
  public class Dog : Animal { public Dog(){_myType = MyAnimals.Dog;} }
  public class Pig : Animal { public Pig(){_myType = MyAnimals.Pig;} }
  
  // 2) Instantiate a class and a variable using the enum
  Dog aDog = new Dog(); // aDog.myType is 'Dog'
  MyAnimals theAnimal; // Will default to 'Cat'
  
  // 3) Change the variable to another enum
  aDog.myType = MyAnimals.Cat; // Error, cant change Type!  Good!
  theAnimal = MyAnimals.Pig;
  
  // 4) Use the variable in a method call
  public void Method( MyAnimals animal ) { ... }
  
  Method( aDog.myType );
  Method( theAnimal );
  </code></pre>
  
  <p>and here is how I do this dynamically.  I can currently get to step 3, but even then it is ugly code.  Can anyone get #4 for me, or help me with this whole situation?</p>
  
  <pre><code>// 1) Create the enum  and classes
  public static Type MyAnimals;
  
  public static dynamic getAnimal(string name)
  {
      dynamic theAnimal = Activator.CreateInstance(MyAnimals); // Will default to 'Cat'
      FieldInfo fi = MyAnimals.GetField(name);
      int iEnum = (int)fi.GetValue(MyAnimals);
      return Enum.ToObject(MyAnimals, iEnum);
  }
  public abstract class Animal { internal dynamic _myType; 
                                 public dynamic myType { get { return _myType; } } }
  public class Cat : Animal { public Cat() { _myType = getAnimal("Cat"); } }
  public class Dog : Animal { public Dog() { _myType = getAnimal("Dog"); } }
  public class Pig : Animal { public Pig() { _myType = getAnimal("Pig"); } }
  
  // Get the current application domain for the current thread.
  AppDomain currentDomain = AppDomain.CurrentDomain;
  
  // Create a dynamic assembly in the current application domain
  AssemblyName aName = new AssemblyName("TempAssembly");
  AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
  
  ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
  
  EnumBuilder eb = mb.DefineEnum("MyAnimalType", TypeAttributes.Public, typeof(int));
  
  var types = new List&lt;Type&gt;();
  int Count = 0;
  foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
      types.AddRange(assembly.GetTypes().Where(x =&gt; x.IsSubclassOf(typeof(Animal))));
  
  foreach (var type in types)
      eb.DefineLiteral(type.Name, Count++);
  
  // Create the type
  MyAnimals = eb.CreateType();
  
  // 2) Instantiate a variable using the enum
  Cat c = new Cat();
  dynamic theAnimal = getAnimal("Pig");
  
  // 3) Change the vairable to another enum
  c.myType = getAnimal("Dog"); // Error, again, good
  theAnimal = getAnimal("Dog");
  
  // 4) Use the variable in a method call
  public void Method( MyAnimals animal ) // Compile error: 'MyAnimals' is a field but used like a type.
  </code></pre>