.net 反射构造你自己的“匿名”对象
由于近来项目的底层架构某些特殊需求及场景的需要要求动态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 反射构造你自己的“匿名”对象的更多相关文章
- 匿名对象 构造方法 重载 构造代码块 this 关键字
一.匿名对象 1.匿名对象 :没有名字对象 2.匿名对象的使用注意点: 1.我们一般不会用匿名对象给属性赋值,无法获取属性值. 2.匿名对象永远都不可能事一个对象. 3.匿名对象的好处 : 书写简单. ...
- 构造 & 析构 & 匿名对象
以前仅知道创建对象,但对匿名对象的了解基本为0. 通过阅读google chromium源代码 中关于 log 的使用,查阅相关资料,了解了一下匿名对象,予以记录. 什么是匿名对象 匿名对象可以理 ...
- JAVA之旅(四)——面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块
JAVA之旅(四)--面向对象思想,成员/局部变量,匿名对象,封装 , private,构造方法,构造代码块 加油吧,节奏得快点了 1.概述 上篇幅也是讲了这点,这篇幅就着重的讲一下思想和案例 就拿买 ...
- Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员、局部),匿名对象的调用,构造代码块(5)
Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员.局部),匿名对象的帝爱用,构造代码块(5)
- 当类型为dynamic的视图模型遭遇匿名对象
当年在ASP.NET MVC 1.0时代我提到,在开发时最好将视图的Model定制为强类型的,这样可以充分利用静态检查功能进行排错.不过有人指出,这么做虽然易于静态检查,但是定义强类型的Model类型 ...
- C++不能显式调用构造函数,会生成匿名对象,这点与Java完全不一样!
Java可以直接调用同名构造函数,仅仅起初始化的功能,并不构造新的对象,但是C++里面没有.看一下这段代码: class A { public: A() { printf("A() \n&q ...
- c# 匿名对象增加动态属性
在开发过程中碰到了一个需求,需要动态创建对象及其动态属性.在尝试几种方法后,最后完成了需求,记录下过程,给园友参考下 1.动态创建对象一:匿名对象 ",Birthday =DateTime. ...
- C# 匿名对象(匿名类型)、var、动态类型 dynamic
本文是要写的下篇<C#反射及优化用法>的前奏,不能算是下一篇文章的基础的基础吧,有兴趣的朋友可以关注一下. 随着C#的发展,该语音内容不断丰富,开发变得更加方便快捷,C# 的锋利尽显无疑. ...
- LINQ学习系列-----1.4 匿名对象
本篇内容接着上一篇继续讲述,本篇简单讲解匿名对象 一.匿名对象介绍 上代码: var result=new { ID=, Name="张三", Age= ...
随机推荐
- 【BZOJ2339】[HNOI2011]卡农 组合数+容斥
[BZOJ2339][HNOI2011]卡农 题解:虽然集合具有无序性,但是为了方便,我们先考虑有序的情况,最后将答案除以m!即可. 考虑DP.如果我们已经知道了前m-1个集合,那么第m个集合已经是确 ...
- SAM4E单片机之旅——10、UART与MCK之PLL
为使用更更高的波特率,则需要更更高的外设时钟的频率.这个时候就需要用到锁相环(PLL)了.锁相环可以对输入的时钟进行分频.升频后进行输出.MCK可以使用的锁相环为PLLA,而PLLA的输入时钟为MAI ...
- EasyDarwin流媒体云平台架构
EasyDarwin目前正在做的开源流媒体云平台架构:
- if __name__ == "__main__": 怎么理解?
参考:https://www.cnblogs.com/Neeo/p/9504779.html 总结: 1.防止模块间调用时,执行被调用模块实例化执行,换句话说,就是不要执行调用模块原来实例化的内容 2 ...
- SpringMVC ajax技术无刷新文件上传下载删除示例
参考 Spring MVC中上传文件实例 SpringMVC结合ajaxfileupload.js实现ajax无刷新文件上传 Spring MVC 文件上传下载 (FileOperateUtil.ja ...
- UVA10870 Recurrences —— 矩阵快速幂
题目链接:https://vjudge.net/problem/UVA-10870 题意: 典型的矩阵快速幂的运用.比一般的斐波那契数推导式多了几项而已. 代码如下: #include <bit ...
- 分布式锁(Redis实现)
1.分布式锁解决方案 1.采用数据库 不建议 性能不好 jdbc 2.基于Redis实现分布式锁(setnx)setnx也可以存入key,如果存入key成功返回1,如果存入的key已经存在了,返回 ...
- IE浏览器没有加载CSS或js文件的秘密及解决办法
其实是两处资料拼成这一篇博文的,因为在开发过程中遇到,有的文章只是说明原因,而没有给出解决方案,所以再次给出解释和解决方法,以供参考,如果有好的解决方法,也请分享下! ---------------- ...
- 调用html进行android布局
1. [代码]html代码 <html> <head> <meta http-equiv="content-type" content ...
- android读取apk中已经存在的数据库信息
在android数据库编程方面,大家有没有遇到过,我要从指定位置的已经存在的数据库来进行操作的问题.之前我尝试了很多方法都没有成功,后来找到了解决的方法. 下面说明下这段代码的意思,第一步先判断在 ...