- 前言
- 一、涉及到的引用
- 二、代码
- 三、 使用方法
- 总结
前言
在对匿名类操作时,参考了一篇博主的文章:https://www.cnblogs.com/elves/p/6087186.html,其中动态类的部分是非常有指导意义的,原博文的动态类是创建字符串属性的动态类,现对其进行加工,略做修改,可以适用创建byte,short,unshort,int,long,bool,float,doubel,List属性(T限于以上基础类型)的动态类。同时因本人年龄偏大,记忆力实在比不上年青人,所以也当做记事本以当纪录。
提示:对以下代码的理解,本人也只是知其部分然,而不尽其所以然,各位观者莫怪,能用最好。
一、涉及到的引用using Microsoft.CSharp; using System; using System.Text; using System.CodeDom.Compiler; using System.Reflection;二、代码
#region 生成自定义动态类
public static class DynamicClassHelper
{
///
/// 创建属性
///
/// 属性基础类型(byte/int/string/float/double/bool等)和List基础类型
/// 属性名称
/// 属性初始值
///
private static string PropertyString(string propertyType, string propertyName, string propertyDefaultValue)
{
StringBuilder sbproperty = new StringBuilder();
sbproperty.Append(" private " + propertyType + " _" + propertyName + " = " + propertyDefaultValue + ";n");
sbproperty.Append(" public " + propertyType + " " + propertyName + "n");
sbproperty.Append(" {n");
sbproperty.Append(" get{ return _" + propertyName + ";} n");
sbproperty.Append(" set{ _" + propertyName + " = value; }n");
sbproperty.Append(" }n");
return sbproperty.ToString();
}
///
/// 创建动态类
///
/// 动态类名字
/// 属性列表
///
public static Assembly Newassembly(string className, List propertyList)
{
//创建编译器实例。
CSharpCodeProvider provider = new CSharpCodeProvider();
//设置编译参数。
CompilerParameters paras = new CompilerParameters();
//编译器生成的临时文件,参数2为true,放置为当前文件夹下,false则放入windows的temp文件夹下
paras.TempFiles = new TempFileCollection(".", false);
//如果为true,则生成exe文件,false会生成临时dll文件
paras.GenerateExecutable = false;
paras.GenerateInMemory = true;
//创建动态代码。
StringBuilder classsource = new StringBuilder();
//float、bool等类型需要引用System
classsource.Append("using System;n");
//List需要引用System.Collections.Generic
classsource.Append("using System.Collections.Generic;n");
classsource.Append("public class " + className + " n");
classsource.Append("{n");
try
{
//创建属性。
for (int i = 0; i < propertyList.Count; i++)
{
classsource.Append(PropertyString(propertyList[i][0], propertyList[i][1], propertyList[i][2]));
}
classsource.Append("}");
System.Diagnostics.Debug.WriteLine(classsource.ToString());
//编译代码。
CompilerResults result = provider.CompileAssemblyFromSource(paras, classsource.ToString());
//获取编译后的程序集。
Assembly assembly = result.CompiledAssembly;
return assembly;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return null;
}
}
///
/// 给属性赋值
///
/// 先进行dynamic objclass = assembly.CreateInstance(className),得到的objclass
/// 属性名称
/// 属性值
public static void ReflectionSetValue(object objclass, string propertyname, object value)
{
PropertyInfo[] infos = objclass.GetType().GetProperties();
try
{
foreach (PropertyInfo info in infos)
{
if (info.Name == propertyname && info.CanWrite)
{
info.SetValue(objclass, value, null);
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
///
/// 得到属性值
///
/// 先进行dynamic objclass = assembly.CreateInstance(className),得到的objclass
/// 属性名称
/// 属性值,是object类型,使用时记得转换
public static object ReflectionGetValue(object objclass, string propertyname)
{
object result = null;
PropertyInfo[] infos = objclass.GetType().GetProperties();
try
{
foreach (PropertyInfo info in infos)
{
if (info.Name == propertyname && info.CanRead)
{
System.Console.WriteLine(info.GetValue(objclass, null));
result = info.GetValue(objclass, null);
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
result = null;
}
return result;
}
}
#endregion
三、 使用方法
1、动态类的属性列表初始化,是List
2、动态类的属性赋值,首先要记得把得到的动态类程序集实例化,就是 dynamic objclass = assembly.CreateInstance(className)这条语句,然后才能进行属性赋值。具体数值原参数为object类,因此,对byte、short、unshort、float等也要强制转换,以下Demo也说得清楚。
///总结/// 例子 /// public static void Demo() { //初始化动态类的属性,并且必须要赋初值,全部用字符串表示, ListPropertys = new List { new string[]{ "byte","studentNo","0"},//byte类型,初始值0或类似(byte)100 new string[]{ "char","level","'A'"},//字符型,用单引号加字符 new string[]{"short","workdate", "(short)100" },//short类型,用0或类似(short)100 new string[] { "int", "id" ,"0"}, new string[] { "string","userName","null"}, new string[]{"bool","sex","true" }, new string[]{"DateTime","jobTime","DateTime.Now" }, new string[]{ "List ","scores","new List ()"}, new string[]{ "double","phonePower","0.0"} }; //创建动态类,构建一个程序集 string className = "Person"; Assembly assembly = DynamicClassHelper.Newassembly(className, Propertys); //构建动态类的实例 dynamic objclass = assembly.CreateInstance(className); //给动态类属性赋值,byte/short/unshort/long/float要强制转换 DynamicClassHelper.ReflectionSetValue(objclass, "studentNo", (byte)10); DynamicClassHelper.ReflectionSetValue(objclass, "level", 'A'); DynamicClassHelper.ReflectionSetValue(objclass, "workdate", (short)300); DynamicClassHelper.ReflectionSetValue(objclass, "id", 1); DynamicClassHelper.ReflectionSetValue(objclass, "userName", "XiaoMing Li"); DynamicClassHelper.ReflectionSetValue(objclass, "sex", true); DynamicClassHelper.ReflectionSetValue(objclass, "jobTime", new DateTime(2015, 8, 1)); DynamicClassHelper.ReflectionSetValue(objclass, "scores", new List { (float)98.2, (float)95.0, (float)88.8 }); DynamicClassHelper.ReflectionSetValue(objclass, "phonePower", 0.89); //获取动态类相应的属性值,因为返回的是object类,要强制转换后使用(List测试时,可以省略强制转换) double phonePower = (double)DynamicClassHelper.ReflectionGetValue(objclass, "phonePower"); List scores = (List )DynamicClassHelper.ReflectionGetValue(objclass, "scores"); }
动态类可能在开发应用中使用的不多,但是对于一些特殊开发需求还是比较有用的。如果此代码能对别人起到帮助作用,我自然也是感到相当欣慰的。



