C#反射、动态生成类
来源:互联网 发布:mac ae2017中英文切换 编辑:程序博客网 时间:2024/05/16 18:56
在软件开发尤其是框架和底层开发时,为了更灵活的控制代码,常常需要进行一些动态的操作。比如根据用户的输入等动态的调用类中的方法或者根据数据库表结构、用户要求动态的生成一些类,然后再动态的调用类中的方法。当然使用这些方式时会对性能有一点影响,具体使用过程中可以根据实际情况来定,不过一般的B/S开发中主要的瓶颈还是在数据库操作和网速方面,这点影响应该可以忽略的
下面我就从这两个方面来说说动态代码的使用:
一、反射的使用
可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
需要使用的命名空间:System.Reflection
反射的作用很多,下面的例子主要是看一下怎么动态的调用类中的方法。
class ReflTest1
{
private string _prop1;
public string Prop1
{
get {return _prop1; }
set { _prop1 = value; }
}
public void Write1(string strText)
{
Console.WriteLine("111111111:"+ strText);
}
public void Write2(string strText)
{
Console.WriteLine("222222222:"+ strText);
}
public void MyWrite(string strText)
{
Console.WriteLine("3333333333:"+ strText);
}
}
这个例子中提供了三个方法和一个属性,下面的代码来动态的调用它们:
string strText ="abcd";
BindingFlags flags = (BindingFlags.NonPublic| BindingFlags.Public|
BindingFlags.Static | BindingFlags.Instance| BindingFlags.DeclaredOnly);
Type t =typeof(ReflTest1);
MethodInfo[] mi = t.GetMethods(flags);
Object obj = Activator.CreateInstance(t);
foreach (MethodInfo min mi)
{
if (m.Name.StartsWith("Write"))
{
m.Invoke(obj, newobject[] { strText });
}
}
MethodInfo mMy = t.GetMethod("MyWrite");
if (mMy !=null)
{
mMy.Invoke(obj, newobject[] { strText });
}
BindingFlags用来设置要取得哪些类型的方法,然后我们就可以取得这些方法来动态的调用。(当然为了可以循环的调用方法,在方法的命名方面可以自己指定一个规则)
二、动态生成类
我们可以在程序运行过程中调用.NET中提供的编译类,动态的将一段string编译成一个类,然后再通过反射来调用它
需要使用的命名空间:System.CodeDom System.CodeDom.Compiler Microsoft.CSharp System.Reflection
动态创建、编译类的代码如下:
public static Assembly NewAssembly()
{
//创建编译器实例。
provider= new CSharpCodeProvider();
//设置编译参数。
paras= new CompilerParameters();
paras.GenerateExecutable= false;
paras.GenerateInMemory= true;
//创建动态代码。
StringBuilder classSource= new StringBuilder();
classSource.Append("public class DynamicClass \n");
classSource.Append("{\n");
//创建属性。
classSource.Append(propertyString("aaa"));
classSource.Append(propertyString("bbb"));
classSource.Append(propertyString("ccc"));
classSource.Append("}");
System.Diagnostics.Debug.WriteLine(classSource.ToString());
//编译代码。
CompilerResults result= provider.CompileAssemblyFromSource(paras, classSource.ToString());
//获取编译后的程序集。
Assembly assembly= result.CompiledAssembly;
return assembly;
}
private staticstring propertyString(string propertyName)
{
StringBuilder sbProperty= new StringBuilder();
sbProperty.Append(" private int _"+ propertyName+ " = 0;\n");
sbProperty.Append(" public int " +"" + propertyName+ "\n");
sbProperty.Append(" {\n");
sbProperty.Append(" get{ return _"+ propertyName+ ";} \n");
sbProperty.Append(" set{ _"+ propertyName+ " = value; }\n");
sbProperty.Append(" }");
return sbProperty.ToString();
}
propertyString方法就是用来拼写字符串的
整个代码比较简单,主要步骤就是:1、拼写类的字符串 2、调用CSharpCodeProvider类进行编译得到程序集(assembly)
接下来就可以利用之前反射的方法来动态调用这个类中的属性了:
Assembly assembly = NewAssembly();
object Class1 = assembly.CreateInstance("DynamicClass");
ReflectionSetProperty(Class1,"aaa", 10);
ReflectionGetProperty(Class1,"aaa");
object Class2 = assembly.CreateInstance("DynamicClass");
ReflectionSetProperty(Class1,"bbb", 20);
ReflectionGetProperty(Class1,"bbb");
DynamicClass是我动态类的类名,aaa和bbb是其中的属性
ReflectionSetProperty和ReflectionGetProperty代码如下:
private staticvoid ReflectionSetProperty(object objClass,string propertyName, int value)
{
PropertyInfo[] infos = objClass.GetType().GetProperties();
foreach (PropertyInfo infoin infos)
{
if (info.Name == propertyName && info.CanWrite)
{
info.SetValue(objClass, value, null);
}
}
}
private staticvoid ReflectionGetProperty(object objClass,string propertyName)
{
PropertyInfo[] infos = objClass.GetType().GetProperties();
foreach (PropertyInfo infoin infos)
{
if (info.Name == propertyName && info.CanRead)
{
System.Console.WriteLine(info.GetValue(objClass, null));
}
}
}
- C#反射、动态生成类
- C#中利用反射,动态生成类的实例
- C#强化系列文章五:动态代码的使用(反射和动态生成类)
- C#强化系列文章五:动态代码的使用(反射和动态生成类)
- C#强化系列文章五:动态代码的使用(反射和动态生成类)
- C#强化系列文章五:动态代码的使用(反射和动态生成类)
- C#反射、动态加载类
- C#反射、动态加载类 .
- C# 动态生成类
- C# 动态生成类
- c#动态生成类
- C# 反射动态判断转换属性类型值生成类实例
- C#反射动态生成对象的关键代码
- C#利用反射动态调用类成员
- 动态代码的使用(反射和动态生成类)
- 动态代码的使用(反射和动态生成类)
- 动态代码的使用(反射和动态生成类)
- 动态代码的使用(反射和动态生成类)
- Java使用Arrays、ArrayList、LinkedList、Vector实现插入查询性能分析
- shell script里面的美元符号什么时候该用
- Spring MVC拦截器的配置
- 开始了真正的programming
- 基于轮廓的匹配算法(强,可在重叠堆积物体中识别)
- C#反射、动态生成类
- 小程序:学生信息管理系统--C语言版本
- ORACLE dba_free_space中没有要找的表空间名字
- 详解div+css相对定位和绝对定位用法
- 只能在执行 Render() 的过程中调用 RegisterForEventValidation;
- 求文件大小的方法
- 使用OLEDB编程
- Android消息队列模型——Thread,Handler,Looper,Massage Queue
- SQL简单分页语句(支持SQL2005及以上)