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:
I am trying to create, and fully use, a dynamic Enumeration Type.
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:
// 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 );
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?
// 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<Type>();
int Count = 0;
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
types.AddRange(assembly.GetTypes().Where(x => 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.