Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Something like this))</p> <pre><code>public abstract class DynamicClass { public override string ToString() { PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); StringBuilder sb = new StringBuilder(); sb.Append("{"); for (int i = 0; i &lt; props.Length; i++) { if (i &gt; 0) sb.Append(", "); sb.Append(props[i].Name); sb.Append("="); sb.Append(props[i].GetValue(this, null)); } sb.Append("}"); return sb.ToString(); } } //DynamicTypeFactory public static class ExpressionHelper //simplified { private const string DYNAMIC_ASSEMBLY_NAME = "DynamicAssembly"; private const string DYNAMIC_MODULE_NAME = "DynamicModule"; private const string DYNAMIC_CLASS_PREFIX = "DynamicClass"; private static ModuleBuilder _moduleBuilder; [SecurityCritical] static ExpressionHelper() { //var assemblyName = new AssemblyName(DYNAMIC_ASSEMBLY_NAME); AssemblyBuilder assembly = Thread.GetDomain().DefineDynamicAssembly(new AssemblyName(DYNAMIC_ASSEMBLY_NAME), AssemblyBuilderAccess.Run); assembly.GetName().SetPublicKey(Assembly.GetExecutingAssembly().GetName().GetPublicKey()); assembly.GetName().SetPublicKeyToken(Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken()); _moduleBuilder = assembly.DefineDynamicModule(DYNAMIC_MODULE_NAME, true); } public static Type CreateType(IDictionary&lt;string, Type&gt; propertyTypes) { var typeName = DYNAMIC_CLASS_PREFIX + propertyTypes.GetHashCode().ToString(); TypeBuilder typeBuilder = _moduleBuilder.DefineType(typeName, TypeAttributes.Class | TypeAttributes.Public, typeof(DynamicClass)); FieldInfo[] fields = GenerateProperties(typeBuilder, propertyTypes); GenerateEquals(typeBuilder, fields); GenerateGetHashCode(typeBuilder, fields); Type result = typeBuilder.CreateType(); return result; } public static object CreateObject(IDictionary&lt;string, object&gt; propertyValues) { var propertyTypes = propertyValues.ToDictionary(pair =&gt; pair.Key, pair =&gt; pair.Value == null ? typeof(object) : pair.Value.GetType()); var type = CreateType(propertyTypes); Expression targetExpression = Expression.New(type.GetConstructors()[0]); var lambda = Expression.Lambda(targetExpression); var target = lambda.Compile().DynamicInvoke(); List&lt;MemberBinding&gt; bindings = new List&lt;MemberBinding&gt;(); foreach (var pair in propertyValues) { bindings.Add(Expression.Bind(type.GetProperty(pair.Key), Expression.Constant(pair.Value))); } return Expression.Lambda(Expression.MemberInit(Expression.New(type), bindings.ToArray())).Compile().DynamicInvoke(); } private static FieldInfo[] GenerateProperties(TypeBuilder typeBuilder, IDictionary&lt;string, Type&gt; propertyTypes) { FieldInfo[] fields = new FieldBuilder[propertyTypes.Count]; for (int i = 0; i &lt; propertyTypes.Count; i++) { var dp = propertyTypes.ElementAt(i); var fb = typeBuilder.DefineField("&lt;" + dp.Key + "&gt;k__BackingField", dp.Value, FieldAttributes.Private); //HasDefault? var pb = typeBuilder.DefineProperty(dp.Key, PropertyAttributes.HasDefault, dp.Value, null); var mbGet = typeBuilder.DefineMethod("get_" + dp.Key, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, dp.Value, Type.EmptyTypes); var getterGenerator = mbGet.GetILGenerator(); getterGenerator.Emit(OpCodes.Ldarg_0); getterGenerator.Emit(OpCodes.Ldfld, fb); getterGenerator.Emit(OpCodes.Ret); //setterBuilder MethodBuilder mbSet = typeBuilder.DefineMethod("set_" + dp.Key, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { dp.Value }); //setterILGenerator var setterGenerator = mbSet.GetILGenerator(); setterGenerator.Emit(OpCodes.Ldarg_0); setterGenerator.Emit(OpCodes.Ldarg_1); setterGenerator.Emit(OpCodes.Stfld, fb); setterGenerator.Emit(OpCodes.Ret); pb.SetGetMethod(mbGet); pb.SetSetMethod(mbSet); fields[i] = fb; } return fields; } private static void GenerateEquals(TypeBuilder typeBuilder, FieldInfo[] fields) { var mb = typeBuilder.DefineMethod("Equals", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(bool), new Type[] { typeof(object) }); var generator = mb.GetILGenerator(); var other = generator.DeclareLocal(typeBuilder); var next = generator.DefineLabel(); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Isinst, typeBuilder); generator.Emit(OpCodes.Stloc, other); generator.Emit(OpCodes.Ldloc, other); generator.Emit(OpCodes.Brtrue_S, next); generator.Emit(OpCodes.Ldc_I4_0); generator.Emit(OpCodes.Ret); generator.MarkLabel(next); foreach (var field in fields) { var ft = field.FieldType; var ct = typeof(EqualityComparer&lt;&gt;).MakeGenericType(ft); next = generator.DefineLabel(); generator.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, field); generator.Emit(OpCodes.Ldloc, other); generator.Emit(OpCodes.Ldfld, field); generator.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null); generator.Emit(OpCodes.Brtrue_S, next); generator.Emit(OpCodes.Ldc_I4_0); generator.Emit(OpCodes.Ret); generator.MarkLabel(next); } generator.Emit(OpCodes.Ldc_I4_1); generator.Emit(OpCodes.Ret); } private static void GenerateGetHashCode(TypeBuilder typeBuilder, FieldInfo[] fields) { var mb = typeBuilder.DefineMethod("GetHashCode", MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof(int), Type.EmptyTypes); var generator = mb.GetILGenerator(); generator.Emit(OpCodes.Ldc_I4_0); foreach (FieldInfo field in fields) { var ft = field.FieldType; var ct = typeof(EqualityComparer&lt;&gt;).MakeGenericType(ft); generator.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, field); generator.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null); generator.Emit(OpCodes.Xor); } generator.Emit(OpCodes.Ret); } } </code></pre> <p>using:</p> <pre><code>var obj = ExpressionHelper.CreateObject(new Dictionary&lt;string, object&gt;() { {"testInt32Property", int.MaxValue}, {"testStringProperty", "TestString"} }); </code></pre>
    singulars
    1. This table or related slice is empty.
    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.
    1. This table or related slice is empty.
    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