c#动态编译和反射Word格式.docx
《c#动态编译和反射Word格式.docx》由会员分享,可在线阅读,更多相关《c#动态编译和反射Word格式.docx(26页珍藏版)》请在冰点文库上搜索。
Sport
{
publicFootball()
{
name="
Football"
;
}
publicoverridestringGetDuration()
return"
four15minutequarters"
publicoverridestringGetName()
returnname;
}
publicclassHockey:
publicHockey()
Hockey"
three20minuteperiods"
publicclassSoccer:
publicSoccer()
Soccer"
two45minutehalves"
下面我们用命令"csc/t:
library/r:
Sport.dllSomeSports.cs"编译该文件.
现在我们有了我们的运动信息dll文件.现在我们想通过程序知道里面有哪些类.请进入最后一步:
第三步:
我们创建文件AssemblyDemo.cs".内容如下:
usingSystem.Reflection;
publicclassAssemblyDemo
publicstaticvoidMain(string[]args)
inti,j;
//==========================
//Firstthecommandlineargumentsareevaluated.ifthereisn'
t
//atleastone,ausagemessageisprinted
//=================================
if(args.GetLength(0)<
1)
Console.WriteLine("
usageisAssemblyDemo<
library_name>
"
);
else
//========================
//AnAssemblyobjectisobtainedfromthecommandlineargument
Assemblyassembly=Assembly.LoadFrom(args[0]);
Type[]types=assembly.GetTypes();
Console.WriteLine(assembly.GetName().Name+"
containsthefollowingtypes"
for(i=0;
i<
types.GetLength(0);
++i)
\r("
+i+"
)"
+types[i].Name);
i=types.Length-1;
Console.Write("
makeselection(0-"
j=Convert.ToInt32(Console.ReadLine());
Console.WriteLine();
if(types[j].IsSubclassOf(typeof(Sport)))
ConstructorInfoci=types[j].GetConstructor(newType[0]);
Sportsport=(Sport)ci.Invoke(newObject[0]);
Console.WriteLine(sport.GetName()+"
has"
+sport.GetDuration());
Console.WriteLine(types[j].Name+"
isnotasub-classofSport"
咱们用命令"csc/r:
Sport.dllAssemblyDemo.cs"编译该文件.
下面我们用"AssemblyDemoSomeSports.dll"运行该程序.
进一步程序要求我们输入选项,咱们输入1,就显示了结果:
Hockeyhasthree20minuteperiods.
好了,今天就到这里了,下面我将进一步说明如何用反射机制访问对象的类型信息.
32
C#反射
(二)
如果没有看《C#反射
(一)》、建议先看《C#反射
(一)》再看这一篇。
上一篇文章发表,有人评论我所写的东西比较基础。
其实我也知道我也只不过是在写最基础的语法而已,之所以写它是因为自己学编程学了一两年之后才接触到反射,相信会有很多人跟我有过同样的经历。
概其原因,书店里几乎90%的书籍都不谈反射。
还有,曾经在XX、goole搜索过反射,但也很难找到自己喜欢的答案。
希望我所写的东西能为那些初学编程的新手有所帮助。
我不想在这里过多的描述反射的概念。
我还是用我自己觉得最简单、最直接的语言来描述反射——“反射就是一种机制,通过这种机制,我们能知道一些位知程序集的详细信息!
”;
通过上一篇我们已经学会如何得到一个未知程序集的相关信息,接下来我要讲的是如何知道未知程序模块的信息:
模块信息是通过Module类访问的。
下面通过一个类子,讲解下Module类的使用,如果你是一个用心的程序员,应该了解下Module的详细信息。
还是继续使用C#反射
(一)的类子。
下面我们写一个新的文件ModuleDemo.cs。
内容如下:
//编译命令csc/r:
Sport.dllModuleDemo.cs
publicclassModuleDemo
//=======================
//AmModuleobjectisobtainedrepresentingthe
//SomeSports.dlllibraryfile
Assemblyassembly=Assembly.Load("
SomeSports"
Modulemodule=assembly.GetModule("
SomeSports.dll"
//======================
//Searchthemoduleforthetypenamed"
Type[]types=module.FindTypes(Module.FilterTypeName,"
if(types.Length!
=0)
ConstructorInfoci=types[0].GetConstructor(newType[0]);
Sportsport=(Sport)ci.Invoke(newObject[0]);
has"
+sport.GetDuration());
typenotfound"
我们用csc/r:
Sport.dllModuleDemo.cs编译,然后用MouduleDemo运行程序就能看到如下输出:
Footballhasfour15minutequarters。
关于C#反射的基础知识,还有一个知识点就是访问未知对象的类型信息。
在下一篇我将介绍它,并介绍我自己曾经写过的一个应用,可以实现具有相同属性或域名的不同类型对象之间的数据相互复制(在Java中可用于J2EE中POJO到FormBean之间的数据复制)。
53
C#动态编译简单剖析
2009-08-2716:
29佚名cnblogs我要评论(0)字号:
T|T
这里介绍C#动态编译,程序会根据类型名称来自动找到符合条件的类并实例化。
如果代码中有多个指定类型的类,将实例化第一个。
C#语言有很多值得学习的地方,这里我们主要介绍C#动态编译,包括介绍公共属性和公共方法等方面。
前几天看到一篇关于C#动态编译的文章,很受启发。
在此基础上我做了一些封装,为使调用更加简单,并增加了对动态代码调试的支持,相同代码只编译一次的支持,代码改动自动重新编译,代码引用文件的自动加载和手工加载等功能。
如上图,我封装的类CSharpProvider很简单,下面说明一下一些公共成员的用法。
公共属性:
◆AssemblyFileName:
这个属性指定C#动态编译后生成的配件名称。
◆CompilerParameters:
这个属性指定编译的参数
◆References:
这个属性指定被编译代码中的引用。
调用者只要调用References.Add("
xxx.dll"
),就可以加入自己的引用,对于System命名空间的所有引用,不需要手工加入,该类会自动加载。
对于用户自己的组件,如果不手工指定引用文件,该类会自动根据名字空间名进行猜测。
◆SourceCodeFileEncoding:
如果以文件形式编译,指定文件的编码类型。
公共方法:
◆publicboolCompile(stringcode)输入代码字符串,并编译
◆publicboolCompileFromFile(stringsourceCodeFileName)编译输入的代码文件
◆publicobjectCreateInstance(stringcode,stringtypeFullName)创建类的实例
如下面代码,可以输入CreateInstance(code,"
MyInterface.IHelloWorld"
),也可以输入CreateInstance(code,"
HelloWorld"
),程序会根据类型名称来自动找到符合条件的类并实例化。
usingMyInterface;
[Serializable]
publicclassHelloWorld:
MarshalByRefObject,IHelloWorld
{
publicstringSay()
return"
Hi"
}
57:
13
c#动态编译
2009-12-2217:
08费亮lewis|分类:
C#/.NET|浏览1756次
我想在c#中通过动态编译实现一个科学计算器器功能,用户直接输入运算表达式即可,如256*56(145+56*254/345).然后通过动态编译返回结果。
请给出代码或例子!
~
比如说:
将textbox1的用户输入语句如256*56(145+56*254/345)利用动态编译求出值后,在textbox2中将结果显示。
我在编写一个矩阵工具,比如用户先导入需要计算的矩阵A,P,L,然后用户可以直接输入类似(AT*PA)'
AT*P*L;
然后通过动态编译返回最终矩阵。
我有更好的答案
提问者采纳
检举|2009-12-2220:
17
要用到C#的编译器、反射功能,自己瞧着去吧
usingMicrosoft.CSharp;
usingSystem.CodeDom.Compiler;
publicclassExample
staticvoidMain()
CSharpCodeProviderprovider=newCSharpCodeProvider();
CompilerParametersparameter=newCompilerParameters();
parameter.ReferencedAssemblies.Add("
System.dll"
parameter.GenerateExecutable=false;
parameter.GenerateInMemory=true;
CompilerResultsresult=provider.CompileAssemblyFromSource(parameter,
CreateCode("
256*56*(145+56.0*254/345)"
));
//将你的式子放在这里
if(result.Errors.Count>
0)
动态编译出错了!
Assemblyassembly=result.CompiledAssembly;
TypeAType=assembly.GetType("
ANameSpace.AClass"
MethodInfomethod=AType.GetMethod("
AFunc"
Console.WriteLine(method.Invoke(null,null));
Console.Read();
staticstringCreateCode(stringpara)
{
namespaceANameSpace{staticclassAClass{publicstaticobjectAFunc(){return"
+para+"
}}}"
25
如何用C#动态编译、执行代码
作者:
Jailu2,745次阅读4条评论
PS:
本文属原博热门文章之一,特原文转载之。
在开始之前,先熟悉几个类及部分属性、方法:
CSharpCodeProvider、ICodeCompiler、CompilerParameters、CompilerResults、Assembly。
一、CSharpCodeProvider
提供对C#代码生成器和代码编译器的实例的访问。
如果要动态生成VB代码,可以使用VBCodeProvider。
CreateCompiler():
获取编译器的实例。
二、ICodeCompiler
定义用于调用源代码编译的接口或使用指定编译器的CodeDOM树。
每种编译方法都接受指示编译器的CompilerParameters对象,并返回指示编译结果的CompilerResults对象。
CompilerAssemblyFromSource(CompilerParametersoption,stringsource):
使用指定的编译器,从包含源代码的字符串设置编译程序集。
三、CompilerParameters
表示用于调用编译器的参数。
ReferencedAssemblies:
获取当前项目所引用的程序集。
Add方法为程序集添加引用。
GenerateExecutable:
获取或设置一个值,该值指示是否生成可执行文件。
若此属性为false,则生成DLL,默认是false。
GenerateInMemory:
获取或设置一个值,该值指示是否在内存中生成输出。
四、CompilerResults
表示从编译器返回的编译结果。
CompiledAssembly:
获取或设置以编译的程序集,Assembly类型。
大致了解以上知识之后,就可以使用C#动态的编译并执行代码了,以下是一段示例程序:
C#
usingSystem.Globalization;
usingSystem.CodeDom;
usingSystem.Text;
namespaceConsoleApplication1
publicclassProgram
staticvoidMain(string[]args)
//1.CSharpCodePrivoder
CSharpCodeProviderobjCSharpCodePrivoder=newCSharpCodeProvider();
//2.ICodeComplier
ICodeCompilerobjICodeCompiler=objCSharpCodePrivoder.CreateCompiler();
//3.CompilerParameters
CompilerParametersobjCompilerParameters=newCompilerParameters();
objCompilerParameters.ReferencedAssemblies.Add("
objCompilerParameters.GenerateExecutable=false;
objCompilerParameters.GenerateInMemory=true;
//4.CompilerResults
CompilerResultscr=objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters,GenerateCode());
if(cr.Errors.HasErrors)
编译错误:
foreach(CompilerErrorerrincr.Errors)
Console.WriteLine(err.ErrorText);
//通过反射,调用HelloWorld的实例
AssemblyobjAssembly=cr.CompiledAssembly;
objectobjHelloWorld=objAssembly.CreateInstance("
DynamicCodeGenerate.HelloWorld"
MethodInfoobjMI=objHelloWorld.GetType().GetMethod("
OutPut"
Console.WriteLine(objMI.Invoke(objHelloWorld,null));
Console.ReadLine();
staticstringGenerateCode()
StringBuildersb=newStringBuilder();
sb.Append("
sb.Append(Environment.NewLine);
namespaceDynamicCodeGenerate"
{"
publicclassHelloWorld"
{"
publicstringOutPut()"