Note that there are some explanatory texts on larger screens.

plurals
  1. POC# output a defined class to a dynamic module using Reflection.Emit
    primarykey
    data
    text
    <p>Microsoft shows how to create a dynamic class here:</p> <p><a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.modulebuilder(v=vs.71).aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/system.reflection.emit.modulebuilder(v=vs.71).aspx</a></p> <p>This defines a custom object, where they define a constructor and a method. I have a class defined, is there a way to emit the class I have already written instead of trying to write it as the example shows?</p> <p>Thanks FacticiusVir, it's nearly complete. However it doesn't seem to be quite there, 'Countries.USA is not supported by the language'</p> <p>Full code including FacticiusVir's answer:</p> <pre><code>class DynamicEnums { public static void Main() { AppDomain domain = AppDomain.CurrentDomain; AssemblyName aName = new AssemblyName("DynamicEnums"); AssemblyBuilder ab = domain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save); ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); ConstructorInfo referenceObjectConstructor = typeof(ReferenceObject).GetConstructor(new[] { typeof(int) }); List&lt;Type&gt; types = new List&lt;Type&gt;(); foreach(ReferenceType rt in GetTypes()) { TypeBuilder tb = mb.DefineType(rt.Name, TypeAttributes.Public); ConstructorBuilder staticConstructorBuilder = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); ILGenerator staticConstructorILGenerator = staticConstructorBuilder.GetILGenerator(); foreach (Reference r in GetReferences(rt.ID)) { string name; if (rt.Name == "Countries") name = r.Abbreviation.Trim(); else if (rt.Name == "PermanentFundDividends") name = "Year" + r.Abbreviation.Trim(); else name = NameFix(r.Name); // Create a public, static, readonly field to store the // named ReferenceObject. FieldBuilder referenceObjectField = tb.DefineField(name, typeof(ReferenceObject), FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.InitOnly); // Add code to the static constructor to populate the // ReferenceObject field: // Load the ReferenceObject's ID value onto the stack as a // literal 4-byte integer (Int32). staticConstructorILGenerator.Emit(OpCodes.Ldc_I4, r.ID); // Create a reference to a new ReferenceObject on the stack // by calling the ReferenceObject(int32 pValue) reference // we created earlier. staticConstructorILGenerator.Emit(OpCodes.Newobj, referenceObjectConstructor); // Store the ReferenceObject reference to the static // ReferenceObject field. staticConstructorILGenerator.Emit(OpCodes.Stsfld, referenceObjectField); } staticConstructorILGenerator.Emit(OpCodes.Ret); types.Add(tb.CreateType()); } try { ab.Save(aName.Name + ".dll"); } catch (Exception) { Console.WriteLine("Could not save .dll, file must already be loaded."); } foreach (Type t in types) { foreach (FieldInfo o in t.GetFields()) { Console.WriteLine("{0}.{1} = {2}", t, o.Name, "Later"); //Don't know how to get Value doing it this way } Console.WriteLine(); //Console.ReadKey(); } Console.WriteLine(); Console.WriteLine("Dynamic Enums Built Successfully."); //Console.ReadKey(); } public static List&lt;ReferenceType&gt; GetTypes() { List&lt;ReferenceType&gt; referenceTypes = new List&lt;ReferenceType&gt;(); referenceTypes.Add(new ReferenceType { ID = 1, Name = "Countries" }); return referenceTypes; } public static List&lt;Reference&gt; GetReferences(int typeID) { List&lt;Reference&gt; references = new List&lt;Reference&gt;(); references.Add(new Reference { ID = 120, Abbreviation = "USA" }); return references; } public struct ReferenceType { public int ID; public string Name; } public struct Reference { public int ID; public int TypeID; public string Abbreviation; public string Name; } public static string NameFix(string name) { //Strip all non alphanumeric characters string r = Regex.Replace(name, @"[^\w]", ""); //Enums cannot begin with a number if (Regex.IsMatch(r, @"^\d")) r = "N" + r; return r; } } public class ReferenceObject { private readonly int value; public ReferenceObject(int pValue) { value = pValue; } public override string ToString() { return value.ToString(); } public int Value() { return value; } public int ID() { return value; } #region == Operator public static bool operator ==(int objLeft, ReferenceObject objRight) { return objLeft == objRight.value; } public static bool operator ==(ReferenceObject objLeft, int objRight) { return objLeft.value == objRight; } public static bool operator ==(string objLeft, ReferenceObject objRight) { return objLeft == objRight.value.ToString(); } public static bool operator ==(ReferenceObject objLeft, string objRight) { return objLeft.value.ToString() == objRight; } #endregion #region != Operator public static bool operator !=(int objLeft, ReferenceObject objRight) { return objLeft != objRight.value; } public static bool operator !=(ReferenceObject objLeft, int objRight) { return objLeft.value != objRight; } public static bool operator !=(string objLeft, ReferenceObject objRight) { return objLeft != objRight.value.ToString(); } public static bool operator !=(ReferenceObject objLeft, string objRight) { return objLeft.value.ToString() != objRight; } #endregion public override bool Equals(object obj) { if ((obj is ReferenceObject)) return value == ((ReferenceObject)obj).value; if ((obj is int)) return value == (int)obj; if ((obj is string)) return value.ToString() == (string)obj; return false; } public override int GetHashCode() { return value; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload