由于近来项目的底层架构某些特殊需求及场景的需要要求动态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. SQL Cursor生命周期

      阅读导航 1 Cursor Step 1.1 Create cursor 1.2 Parse statement 1.3 descript and define 1.4 Bind variable ...

  2. Nmap扫描教程之基础扫描具体解释

    Nmap扫描教程之基础扫描具体解释 Nmap扫描基础扫描 当用户对Nmap工具了解后,就可以使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具能够分别对主机.port.版本号.操作系统等实施扫 ...

  3. 实现单击列表头对ListView的动态排序

    排序是根据列的类型来的,就ID列来说,int类型的排序结果是3,5,17,而如果你把该列类型改为string,结果就会是17,3,5,如果你定义列的时候不加类型,默认是string,如果是自定义类型, ...

  4. ios 使用自定义字体

    本文转载至 http://blog.csdn.net/yesjava/article/details/8447596   1.下载要使用的自定义字体,格式通常为ttf.otf文件.这里假设是nokia ...

  5. 使用unidac 连接FB 3.0 (含嵌入版)

    unidac  是delphi 最强大的数据库连接控件,没有之一.详细信息可以通过官网了解. Firebird是一个跨平台的关系数据库系统,目前能够运行在Windows.linux和各种Unix操作系 ...

  6. 九度OJ 1090:路径打印 (树、DFS)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1704 解决:314 题目描述: 给你一串路径,譬如: a\b\c a\d\e b\cst d\ 你把这些路径中蕴含的目录结构给画出来,子目 ...

  7. 九度OJ 1085:求root(N, k) (迭代)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1407 解决:523 题目描述: N<k时,root(N,k) = N,否则,root(N,k) = root(N',k).N'为N的 ...

  8. exp/imp三种模式——完全、用户、表

    ORACLE数据库有两类备份方法.第一类为物理备份,该方法实现数据库的完整恢复,但数据库必须运行在归挡模式下(业务数据库在非归挡模式下运行),且需要极大的外部存储设备,例如磁带库:第二类备份方式为逻辑 ...

  9. Windows消息、绘图与多线程

    有一个项目,一旦点下按钮后,用死循环不停的读数据,读出后立刻用可视化的方法显示.如果不采用多线程的方法,程序运行都正确,但无法关闭窗口,不清楚是窗口无法通过关闭按钮来接受Windows消息,还是接受了 ...

  10. myeclipse10集成Tomcat6时出现错误

    myeclipse配置Tomcat时出现错误:如图 tomcat6目录:如图 在搜集各种资料后,最终得出结论: 在Tomcat目录中新建temp文件夹,问题解决. 亲测好使.