Natasha 高级编译类 (五)- 第二部分
FakeMethodOperator
将以后的方法进行快速克隆,克隆时只会覆盖重新声明的信息,例如原来是public类型,不做定义的话,就直接拿过来使用。
好处:写好的模板不需要大变,变动的地方又代码进行修改
注意:使用Compile方法进行编译,参数为带入的参数,可通过调用.Compile().GetMethodInfo().Invoke()进行方法调用
-
需要克隆的类及用到的代理
///////////////需要使用的克隆类////////////////////// /// <summary> /// 等待克隆的类 /// </summary> public class OopTestModel { /// <summary> /// 最基本的方法 /// </summary> public void ReWrite1() {} /// <summary> /// 并发执行的方法 /// </summary> /// <returns></returns> public async Task<OopTestModel> ReWrite2() {return this;} /// <summary> /// 虚方法,并带有ref和out /// </summary> /// <param name="i"></param> /// <param name="temp"></param> /// <returns></returns> public virtual ref int ReWrite3(ref int i, out string temp) { temp = default!; return ref i; } } /// <summary> /// 虚方法声明的代理类 /// </summary> /// <param name="i"></param> /// <param name="temp"></param> /// <returns></returns> public delegate ref int TestDelegate1(ref int i, out string temp);
-
实现类
// 引用第一个方法,最简单的调用 var builder1 = FakeMethodOperator.DefaultDomain(); builder1 // 克隆OopTestModel的ReWrite1方法,加上!表示可以为null .UseMethod(typeof(OopTestModel).GetMethod("ReWrite1")!) // 方法体中加入下面方法 .MethodBody(@"Console.WriteLine(""hello world"");"); System.Console.WriteLine(builder1.ScriptCache); // 引用第二个方法,并发执行的方法 var builder2 = FakeMethodOperator.DefaultDomain() // 克隆OopTestModel的ReWrite2方法 .UseMethod(typeof(OopTestModel).GetMethod("ReWrite2")!) // 静态的方法体,注意,该处看不出是async的并发方法 .StaticMethodBody(@"Console.WriteLine(""hello world"");return default;"); if (builder2.Compile() != null) { System.Console.WriteLine(builder2.ScriptCache); }else{ System.Console.WriteLine("未编译成功"); } //引用第三个,改为静态方法 var builder3 = FakeMethodOperator.DefaultDomain(); builder3 // 克隆OopTestModel的ReWrite3方法 .UseMethod(typeof(OopTestModel).GetMethod("ReWrite3")!) // 改为静态方法并设置方法体 .StaticMethodBody(@"temp = default;return ref i;"); //编译 加入代理 if (builder3.Compile<TestDelegate1>() != null) { System.Console.WriteLine(builder3.ScriptCache); } else { System.Console.WriteLine("未编译成功"); }
运行结果
FastMethodOperator
用于快速构建方法并执行
注意:实例化的方法为Invoke,类似于反射
//最简单的快速调用
var delegateAction1 = FastMethodOperator
.DefaultDomain()
.Param<string>("str1")
.Param<string>("str2")
.Body(@"
string result = str1 +"" ""+ str2;
return result;")
.Return<string>()
// 编译
.Compile<Func<string, string, string>>();
// 执行
System.Console.WriteLine(delegateAction1.Invoke("Hello", "World1!"));
// delegateAction1的简化版,无需Param和Result
var delegateAction2 = FastMethodOperator.DefaultDomain()
.Body(@"return arg1 +"" ""+ arg2;")
.Compile<Func<string, string, string>>();
System.Console.WriteLine(delegateAction2.Invoke("Hello", "World2!"));
//并发执行的方法
// 注意执行该方法时一定要使用await或者Sleep,否则不会输出
var delegateAction3 = FastMethodOperator.DefaultDomain()
.Async()
.Body(@"
await Task.Delay(100);
string result = arg1 +"" ""+ arg2;
return result;")
.Compile<Func<string, string, Task<string>>>();
System.Console.Write
执行结果
NInterface
Natasha版本的接口快速构建
var builder = NInterface.DefaultDomain();
builder.AssemblyBuilder.DisableSemanticCheck();
var type = builder
.NoGlobalUsing()
.HiddenNamespace()
.Access(AccessFlags.Public)
.Name("Interface1")
.Property(item => item.Type<string>().Name("Abc"))
.Method(item => item.Name("Test").Param<string>("p").Return<int>())
.GetType();
System.Console.WriteLine(builder.AssemblyBuilder.SyntaxTrees[0].ToString());
执行结果
NInstance
直接实例化一个类NInstance.Creator
///待初始化类
public class CallModel
{
public CallModel()
{
Age = "World!";
CreateTime = DateTime.Now;
}
public string Age;
public DateTime CreateTime;
public String getCall() {
return $"{Age}:{CreateTime}";
}
}
// 调用
var instance = NInstance.Creator<CallModel>();
var callModel = instance.Invoke();
System.Console.WriteLine(callModel.getCall());
执行结果
未完待续。。。