由于近来项目的底层架构某些特殊需求及场景的需要要求动态build一个对象,

属性名称个类与类型都是外界动态传入的。

不多说废话,直接上我最原始的代码:

         public static Type GetMyType()
{
string[] namelist = new string[] { "UserName", "UserID" };
Dictionary<string, Type> dic = new Dictionary<string, Type>();
dic.Add("UserName", typeof(string));
dic.Add("UserID", typeof(int)); string strDynamicModuleName = "jksdynamic";
string strDynamicClassName = "<>jksdynamci";
AppDomain currentDomain = System.AppDomain.CurrentDomain;
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = strDynamicModuleName; AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(strDynamicModuleName); TypeBuilder typeBuilder = moduleBuilder.DefineType(strDynamicClassName, TypeAttributes.Public); Type[] methodArgs = { typeof(string) }; ConstructorBuilder constructorBuiler = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(string), typeof(int) }); // typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard);
//typeBuilder.d
//动态创建字段
// FieldBuilder fb = typeBuilder.DefineField(item, typeof(System.String), FieldAttributes.Private);
//ILGenerator ilg = constructorBuiler.GetILGenerator();//生成 Microsoft 中间语言 (MSIL) 指令
//ilg.Emit(OpCodes.Ldarg_0);
//ilg.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
//ilg.Emit(OpCodes.Ldarg_0);
//ilg.Emit(OpCodes.Ldarg_1); ////ilg.Emit(OpCodes.Stfld);
//ilg.Emit(OpCodes.Ret); int index = ;
ILGenerator ilg = constructorBuiler.GetILGenerator();
foreach (string item in dic.Keys)
{ //typeBuilder.DefineConstructor(MethodAttributes.Assembly, CallingConventions.VarArgs, new Type[] { typeof(string), typeof(int) }); //动态创建字段
//FieldBuilder fb = typeBuilder.DefineField("_" + item, dic[item], FieldAttributes.Private); //类型的属性成员由两部分组成,一是私有字段,二是访问私有字段的属性包装器。
//包装器运行时的本质与 Method 一样,即包含 Set_Method 和 Get_Method 两个方法。
//动态创建字段
FieldBuilder fieldBuilder = typeBuilder.DefineField(dic[item].Name + "_" + item, dic[item], FieldAttributes.Public); //FieldBuilder conFieldBuilder = typeBuilder.DefineField(item.ToLower(), dic[item], FieldAttributes.Public); index++;
ilg.Emit(OpCodes.Ldarg_0);//向MSIL流发送属性实例
ilg.Emit(OpCodes.Ldarg, index);//将指定索引的参数加到堆栈上。
ilg.Emit(OpCodes.Stfld, fieldBuilder);//装载字段 //ilg.Emit(OpCodes.Stfld, fieldBuilder); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(item, PropertyAttributes.None, dic[item], null);
//MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
MethodBuilder methodBuilder = typeBuilder.DefineMethod("get_" + item, MethodAttributes.Public, dic[item], null); ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder);//装载属性私有字段
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(methodBuilder);// 设置获取属性值的方法 methodBuilder = typeBuilder.DefineMethod("set_" + item,
MethodAttributes.Public,
typeof(void), new Type[] { dic[item] }); ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(methodBuilder);// 设置属性值的方法 }
ilg.Emit(OpCodes.Ret);
Type type = typeBuilder.CreateType(); //Type typeDynamic = moduleBuilder.GetType(strDynamicClassName);
//object objReturn = Activator.CreateInstance(typeDynamic, "Admin", 90); object objReturn = Activator.CreateInstance(type, "Admin", ); return 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.

测试代码如下:

         public static void TestCreateType()
{
Type myDynamicType = GetMyType();
Console.WriteLine("Some information about my new Type '{0}':",
myDynamicType.FullName);
Console.WriteLine("Assembly: '{0}'", myDynamicType.Assembly);
Console.WriteLine("Attributes: '{0}'", myDynamicType.Attributes);
Console.WriteLine("Module: '{0}'", myDynamicType.Module);
Console.WriteLine("Members: ");
foreach (MemberInfo member in myDynamicType.GetMembers())
{
Console.WriteLine("-- {0} {1};", member.MemberType, member.Name);
}
Console.WriteLine("---");
Type[] aPtypes = new Type[] { typeof(string), typeof(int) }; object[] aPargs = new object[] { "JksName", }; ConstructorInfo myDTctor = myDynamicType.GetConstructor(aPtypes);
Console.WriteLine("Constructor: {0};", myDTctor.ToString()); Console.WriteLine("---"); object amyclass = myDTctor.Invoke(aPargs);
Console.WriteLine("aPoint is type {0}.", amyclass.GetType()); //Console.WriteLine("aPoint.x = {0}",
// myDynamicType.InvokeMember("get_UserName",
// BindingFlags.InvokeMethod,
// null,
// myDTctor,
// new object[0]));
Console.WriteLine("Method ---");
foreach (MethodInfo method in myDynamicType.GetMethods())
{
if (method.Name.StartsWith("get_"))
{
object v = method.Invoke(amyclass, null);
Console.WriteLine(method.Name + " : " + v.ToString());
}
}
Console.WriteLine("Property ---");
foreach (PropertyInfo property in myDynamicType.GetProperties())
{ Console.WriteLine(property.Name + " : " + property.GetValue(amyclass).ToString()); } }

运行结果如下:

.net 反射构造你自己的“匿名”对象的更多相关文章

  1. 匿名对象 构造方法 重载 构造代码块 this 关键字

    一.匿名对象 1.匿名对象 :没有名字对象 2.匿名对象的使用注意点: 1.我们一般不会用匿名对象给属性赋值,无法获取属性值. 2.匿名对象永远都不可能事一个对象. 3.匿名对象的好处 : 书写简单. ...

  2. 构造 & 析构 & 匿名对象‍

    ‍以前仅知道创建对象,但对匿名对象的了解基本为0. 通过阅读google chromium源代码 中关于 log 的使用,查阅相关资料,了解了一下匿名对象,予以记录. 什么是匿名对象‍ 匿名对象可以理 ...

  3. JAVA之旅(四)——面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块

    JAVA之旅(四)--面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块 加油吧,节奏得快点了 1.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买 ...

  4. Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员、局部),匿名对象的调用,构造代码块(5)

    Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员.局部),匿名对象的帝爱用,构造代码块(5)

  5. 当类型为dynamic的视图模型遭遇匿名对象

    当年在ASP.NET MVC 1.0时代我提到,在开发时最好将视图的Model定制为强类型的,这样可以充分利用静态检查功能进行排错.不过有人指出,这么做虽然易于静态检查,但是定义强类型的Model类型 ...

  6. C++不能显式调用构造函数,会生成匿名对象,这点与Java完全不一样!

    Java可以直接调用同名构造函数,仅仅起初始化的功能,并不构造新的对象,但是C++里面没有.看一下这段代码: class A { public: A() { printf("A() \n&q ...

  7. c# 匿名对象增加动态属性

    在开发过程中碰到了一个需求,需要动态创建对象及其动态属性.在尝试几种方法后,最后完成了需求,记录下过程,给园友参考下 1.动态创建对象一:匿名对象 ",Birthday =DateTime. ...

  8. C# 匿名对象(匿名类型)、var、动态类型 dynamic

    本文是要写的下篇<C#反射及优化用法>的前奏,不能算是下一篇文章的基础的基础吧,有兴趣的朋友可以关注一下. 随着C#的发展,该语音内容不断丰富,开发变得更加方便快捷,C# 的锋利尽显无疑. ...

  9. LINQ学习系列-----1.4 匿名对象

    本篇内容接着上一篇继续讲述,本篇简单讲解匿名对象 一.匿名对象介绍              上代码: var result=new { ID=, Name="张三", Age= ...

随机推荐

  1. smartUpload注意过程

    操作的过程中一定要注意的几个方面:       1.将smartUpload.jar拷贝到tomcat/lib以及项目的lib下面,最好是只多不少!       2.因为上传的文件一般都很大,所以应该 ...

  2. UltimateRecyclerView的用法具体解释

    近期在用非常多第三方库的时候,发现有一些附带的demo写的不是非常全面或者样例的代码太多,凝视太少,要想使用还要去看下源代码什么的(.. .用第三方开源库不就是想节省时间嘛).所以决定每周两到三篇.写 ...

  3. tween用户使用指南

    tween.js user guide tween.js用户指南 1.What is a tween? How do they work? Why do you want to use them? 一 ...

  4. 循序渐进学Python2变量与输入

    新建一个test.py文件,右键选择“Edit with IDLE”,编辑完成后,Ctrl+S保存,然后按下F5就可以执行代码了. 注:IDLE是Python官方提供的一个IDE工具. 目录 [隐藏] ...

  5. iOS进程间通信之CFMessagePort

    本文转载至 http://www.cocoachina.com/industry/20140606/8701.html iOS系统是出了名的封闭,每个应用的活动范围被严格地限制在各自的沙盒中.尽管如此 ...

  6. springboot中tomcat找不到jsp页面【转载】

    这个原理还没搞明白,只知道是内嵌的tomcat找jsp时默认不读取resources目录,但是具体的默认读取的是哪个目录,打了一下午断点我也没找到.... 修改方式,添加配置修改tomcat的读取目录 ...

  7. Java多线程学习(吐血超详细总结)转自博主林炳文Evankaka

    文章由林炳文Evankaka原创.转载自http://blog.csdn.net/evankaka 写在前面的话:此文只能说是Java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果 ...

  8. Nothing but the key 属性全部依赖于主键 third norm form

    全依赖 Designs that Violate 1NF CustomerCustomer ID First Name Surname Telephone Number123 Pooja Singh ...

  9. Machine Learning in Action(3) 朴素贝叶斯算法

    贝叶斯决策一直很有争议,今年是贝叶斯250周年,历经沉浮,今天它的应用又开始逐渐活跃,有兴趣的可以看看斯坦福Brad Efron大师对其的反思,两篇文章:“Bayes'Theorem in the 2 ...

  10. jQuery事件函数位置放置的两种方法

    jQuery 事件函数 jQuery 事件处理方法是 jQuery 中的核心函数. 事件处理程序指的是当 HTML 中发生某些事件时所调用的方法. 通常会把 jQuery 代码放到 <head& ...