Natasha 高级编译类 (五)- 第二部分

发布时间 2023-04-25 08:21:00作者: 摧残一生

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());

执行结果

未完待续。。。