前言
在对匿名类操作时,参考了一篇博主的文章: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
{
/// <summary>
/// 创建属性
/// </summary>
/// <param name="propertyType">属性基础类型(byte/int/string/float/double/bool等)和List基础类型</param>
/// <param name="propertyName">属性名称</param>
/// <param name="propertyDefaultValue">属性初始值</param>
/// <returns></returns>
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();
}
/// <summary>
/// 创建动态类
/// </summary>
/// <param name="className">动态类名字</param>
/// <param name="propertyList">属性列表</param>
/// <returns></returns>
public static Assembly Newassembly(string className, List<string[]> 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;
}
}
/// <summary>
/// 给属性赋值
/// </summary>
/// <param name="objclass">先进行dynamic objclass = assembly.CreateInstance(className),得到的objclass</param>
/// <param name="propertyname">属性名称</param>
/// <param name="value">属性值</param>
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);
}
}
/// <summary>
/// 得到属性值
/// </summary>
/// <param name="objclass">先进行dynamic objclass = assembly.CreateInstance(className),得到的objclass</param>
/// <param name="propertyname">属性名称</param>
/// <returns>属性值,是object类型,使用时记得转换</returns>
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<string[]>类型,其中string[]数组有三个字符串组成,第一个是属性的类型,第二个是属性名称,第三个是属性的初始值,这三项都必须填写,否则将无法构建属性列表。对于byte、short、unshort、long可用"0"进行初始化,其他数值要用到相应的强制转换类型符。
2、动态类的属性赋值,首先要记得把得到的动态类程序集实例化,就是 dynamic objclass = assembly.CreateInstance(className)这条语句,然后才能进行属性赋值。具体数值原参数为object类,因此,对byte、short、unshort、float等也要强制转换,以下Demo也说得清楚。文章来源:https://www.toymoban.com/news/detail-514006.html
/// <summary>
/// 例子
/// </summary>
public static void Demo()
{
//初始化动态类的属性,并且必须要赋初值,全部用字符串表示,
List<string[]> Propertys = new List<string[]>
{
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<float>","scores","new List<float>()"},
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> { (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<float> scores = (List<float>)DynamicClassHelper.ReflectionGetValue(objclass, "scores");
}
总结
动态类可能在开发应用中使用的不多,但是对于一些特殊开发需求还是比较有用的。如果此代码能对别人起到帮助作用,我自然也是感到相当欣慰的。文章来源地址https://www.toymoban.com/news/detail-514006.html
到了这里,关于C# 动态类创建、动态创建属性和取动态类属性值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!