首先我们来详细讲解一下如何在C#中动态编译执行对象方法,具体步骤包括以下几个方面:
1.使用C#动态编译器进行编译
2.使用反射获取程序集,类型以及方法
3.创建对象实例并执行方法
步骤1:使用C#动态编译器进行编译
使用C#动态编译器可以将代码字符串编译成程序集,代码示例如下:
string code = @"using System;
public class DynamicCode
{
public int Add(int a, int b){
return a + b;
}
}";
var provider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } });
var options = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true };
var result = provider.CompileAssemblyFromSource(options, code);
if (result.Errors.HasErrors)
{
StringBuilder builder = new StringBuilder();
foreach (CompilerError error in result.Errors)
{
builder.AppendLine(String.Format("{0},{1},{2}", error.Line, error.Column, error.ErrorText));
}
throw new InvalidOperationException(builder.ToString());
}
var ass = result.CompiledAssembly;
使用上述代码编译DynamicCode类,该类包含Add方法。
步骤2:使用反射获取程序集、类型以及方法
使用反射动态加载程序集、获取类型以及方法的过程中包括以下几个方面:
1.加载程序集,通过调用Assembly.Load(byte[])方法加载动态构建的程序集
2.获取类型(object)
3.获取方法(MethodInfo)
var bytes = System.IO.File.ReadAllBytes(@"DynamicCode.dll");
Assembly assembly = Assembly.Load(bytes);
Type type = assembly.GetType("DynamicCode");
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("Add");
步骤3:创建对象实例并执行方法
使用反射调用MethodInfo.Invoke(object, object[])方法,即可执行方法:
var result = method.Invoke(instance, new object[] { 1, 2 });
Console.WriteLine("1+2={0}", result);
至此,动态编译执行对象方法示例的攻略已经介绍完了。
下面我们来看一下示例:
示例1:动态生成序列化类并执行序列化方法
首先我们定义一个Person类:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
接下来我们使用动态编译器生成一个序列化类:
string code = @"using System.IO;
using System.Runtime.Serialization.Json;
public class JsonHelper
{
public static string Serialize(object obj)
{
var serializer = new DataContractJsonSerializer(obj.GetType());
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
return System.Text.Encoding.UTF8.GetString(ms.ToArray());
}
}
}";
var provider = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } });
var options = new CompilerParameters() { GenerateExecutable = false, GenerateInMemory = true };
var result = provider.CompileAssemblyFromSource(options, code);
if (result.Errors.HasErrors)
{
StringBuilder builder = new StringBuilder();
foreach (CompilerError error in result.Errors)
{
builder.AppendLine(String.Format("{0},{1},{2}", error.Line, error.Column, error.ErrorText));
}
throw new InvalidOperationException(builder.ToString());
}
var ass = result.CompiledAssembly;
接下来我们使用上述序列化类来序列化一个Person对象:
var bytes = System.IO.File.ReadAllBytes(@"DynamicCode.dll");
Assembly assembly = Assembly.Load(bytes);
Type type = assembly.GetType("JsonHelper");
MethodInfo method = type.GetMethod("Serialize");
var person = new Person() { Name = "Tom", Age = 18 };
var result = method.Invoke(null, new object[] { person });
Console.WriteLine(result);
通过以上方法我们成功通过动态编译器生成了一个序列化类,并且创建了一个Person对象并将其序列化。
示例2:动态创建对象实例并利用映射机制调用方法
首先我们定义一个Calculator类:
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
public int Multiply(int a, int b)
{
return a * b;
}
public int Divide(int a, int b)
{
if (b == 0)
{
throw new DivideByZeroException();
}
return a / b;
}
}
接下来我们使用映射机制来调用Calculator类中的Add、Sub、Multiply和Divide方法:
var bytes = System.IO.File.ReadAllBytes(@"DynamicCode.dll");
Assembly assembly = Assembly.Load(bytes);
Type type = assembly.GetType("Calculator");
object calc = Activator.CreateInstance(type);
var methods = type.GetMethods();
Dictionary<string, MethodInfo> dictionary = new Dictionary<string, MethodInfo>();
foreach (var method in methods)
{
dictionary.Add(method.Name, method);
}
int a = 10, b = 5;
MethodInfo add = dictionary["Add"];
int result = (int)add.Invoke(calc, new object[] { a, b });
Console.WriteLine("{0} + {1} = {2}", a, b, result);
MethodInfo sub = dictionary["Sub"];
result = (int)sub.Invoke(calc, new object[] { a, b });
Console.WriteLine("{0} - {1} = {2}", a, b, result);
MethodInfo mul = dictionary["Multiply"];
result = (int)mul.Invoke(calc, new object[] { a, b });
Console.WriteLine("{0} * {1} = {2}", a, b, result);
MethodInfo div = dictionary["Divide"];
result = (int)div.Invoke(calc, new object[] { a, b });
Console.WriteLine("{0} / {1} = {2}", a, b, result);
通过以上方法我们成功使用映射机制调用了Calculator类中的方法。
至此,我们通过两个示例详细讲解了如何在C#中动态编译执行对象方法,并且利用映射机制来调用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c#动态编译执行对象方法示例 运用映射机制创建对象 - Python技术站