由於近來項目的底層架構某些特殊需求及場景的需要要求動態build一個對象,
屬性名稱個類與類型都是外界動態傳入的。
不多說廢話,直接上我最原始的代碼:
[] namelist = [] { , Dictionary<, Type> dic = Dictionary<, Type> dic.Add(, ( dic.Add(, ( strDynamicModuleName = strDynamicClassName = AppDomain currentDomain = AssemblyName assemblyName = assemblyName.Name = AssemblyBuilder assemblyBuilder = ModuleBuilder moduleBuilder = TypeBuilder typeBuilder = Type[] methodArgs = { ( ConstructorBuilder constructorBuiler = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type[] { (), ( index = ILGenerator ilg = ( item FieldBuilder fieldBuilder = typeBuilder.DefineField(dic[item].Name + + index++ ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldarg, index); ilg.Emit(OpCodes.Stfld, fieldBuilder); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(item, PropertyAttributes.None, dic[item], MethodBuilder methodBuilder = typeBuilder.DefineMethod( + item, MethodAttributes.Public, dic[item], ILGenerator ilGenerator = ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); propertyBuilder.SetGetMethod(methodBuilder); methodBuilder = typeBuilder.DefineMethod( + (), ilGenerator = propertyBuilder.SetSetMethod(methodBuilder); Type type = objReturn = Activator.CreateInstance(type, , }
特別說:
ldarg.0微軟官網上的說明,這裡不做翻譯比較簡單。
NOTE: ldarg.0 holds the "this" reference - ldarg.1, ldarg.2, and ldarg.3
hold the actual passed parameters. ldarg.0 is used by instance methods
to hold a reference to the current calling object instance. Static methods
do not use arg.0, since they are not instantiated and hence no reference
is needed to distinguish them.
測試代碼如下:
Type myDynamicType = Console.WriteLine( Console.WriteLine( Console.WriteLine( Console.WriteLine( Console.WriteLine( (MemberInfo member Console.WriteLine( Console.WriteLine( Type[] aPtypes = Type[] { (), ( [] aPargs = [] { , ConstructorInfo myDTctor = Console.WriteLine( Console.WriteLine( amyclass = Console.WriteLine( Console.WriteLine( (MethodInfo method (method.Name.StartsWith( v = method.Invoke(amyclass, Console.WriteLine(method.Name + + Console.WriteLine( (PropertyInfo property Console.WriteLine(property.Name + + }
運行結果如下: