Natasha V5.2.2.1 稳定版正式发布.
阅读原文时间:2023年07月09日阅读:1
  • 使用 NMS Template 接管 CI 的部分功能.
  • 取消 SourceLink.GitHub 的继承性.
  • 优化几处内存占用问题.
  • 增加隐式 using 配置文件以支持隐式 using 引用. 当项目开启 <ImplicitUsings>enable</ImplicitUsings> 时,自动生效.
  • 增加初始化 PE 信息判断, 跳过无效 DLL 文件.
  • 整改 AssemblyCSharpBuilder, 修改几处 API:
    • 增加 GetAvailableCompilation, 开发者使用此API可以进行单独编译信息整合以及语义语法修剪,其结果为 Compilation 属性, 为下一步编译程序集做准备.
    • 增加 ClearCompilationCache 移除当前 编译单元的编译信息, 运行 GetAvailableCompilation/GetAssembly 将重新构建编译信息.
    • 增加 WithRandomAssenblyName 将当前编译单元的程序集名更改为 GUID 随机名.
    • 增加 ClearScript 清除当前编译单元储存的所有C#脚本代码.
    • 增加 Clear 清除脚本代码,清除编译信息,清除程序集名.
  • 增加一个节省性能开销的 API.
    • AnalysisIgnoreAccessibility(), 调用此方法,语义检测将检测元数据的访问级别,可能增加性能开销.
    • NotAnalysisIgnoreAccessibility(), 调用此方法,语义检测将忽视检测元数据的访问级别,降低开销(编译单元默认使用的是低开销方案), 安全编程请选择此项.
  • 编译单元增加两个方便操作的 API.
    • AddWithFullUsing(script): 增加脚本时,默认覆盖全域的 Using 引用.
    • AddWithDefaultUsing(script): 增加脚本时,默认覆盖主域的 Using 引用.
  • 新增 Type 的扩展 API:
    • GetDelegateFromType , 参考 GetDelegateFromShortName 的用法.
  • [破坏性更改] 下列 API, 从 AssemblyCSharpBuilder 的扩展方法 更改为 Assembly 类型的扩展方法:
    • GetTypeFromShortName / GetTypeFromFullName,
    • GetMethodFromShortName / GetMethodFromFullName
    • GetDelegateFromShortName / GetDelegateFromFullName

使用迁移: builder.GetDelegateFromShortName() 更改为 builder.GetAssembly().GetDelegateFromShortName();

builder.GetAssembly() 仍然不可多次编译, 请及时缓存结果.

  • 取消 SourceLink.GitHub 的继承性.

  • 增加 全局 using 配置文件以支持全局 using 引用.

    internal class Program
    {
        static void Main(string[] args)
        {
            //准备工作
            NatashaManagement.Preheating();
            AssemblyCSharpBuilder builder = new();
            builder.Domain = DomainManagement.Random();
        //填充一个
        builder.AddWithDefaultUsing("public class A { }");
        //此 API 可以在不用编译的情况下获取到已经格式化好的语法树.
        //注: GetAssembly 方法中已包括此方法, 但不会重复运行.
        builder.GetAvailableCompilation();
        var assemblyA = builder.GetAssembly();
        ShowAssemblyInfo(assemblyA);
        ShowSyntaxTree(builder.Compilation!);
    
        //清除编译信息,使 builder 可以重新组合 编译信息.
        builder.ClearCompilationCache();
        //重置程序集名,以免编译时产生冲突.
        builder.WithRandomAssenblyName();
        //向 builder 中追加类型 B.
        builder.AddWithDefaultUsing("public static class B{ public static void Show(){ Console.WriteLine(\"HelloWorld!\"); } }");
    
        var assemblyAB = builder.GetAssembly();
        ShowAssemblyInfo(assemblyAB);
        ShowSyntaxTree(builder.Compilation!);
    
        //反射方法并生成委托
        var action = assemblyAB.GetDelegateFromShortName&lt;Action&gt;("B", "Show");
        Console.WriteLine("运行方法:");
        action();
    
        //action.DisposeDomain();
        //Console.WriteLine(DomainManagement.IsDeleted(builder.Domain!.Name!));
        Console.ReadKey();
    
        static void ShowAssemblyInfo(Assembly assembly)
        {
    
            Console.WriteLine("此程序集名字:"+assembly.FullName);
            Console.WriteLine("此程序集是否为动态程序集:" + (assembly.IsDynamic ? "是" : "否"));
            Console.WriteLine("编译后的程序集中类的数量:" + assembly.GetTypes().Length);
            Console.WriteLine("程序集中的类分别是:" + string.Join(",", assembly.GetTypes().Select(item =&gt; item.Name)));
    
        }
    
        static void ShowSyntaxTree(Compilation compilation)
        {
            Console.WriteLine("---------------------------");
            foreach (var item in compilation.SyntaxTrees)
            {
                Console.WriteLine("脚本代码:");
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("---------------------------");
        }
    }
    }

结果如下:

此程序集名字:9a7962dc0b004c2481d615c5e044c6df, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
此程序集是否为动态程序集:否
编译后的程序集中类的数量:3
程序集中的类分别是:EmbeddedAttribute,RefSafetyRulesAttribute,A
-----------脚本代码-----------
public class A
{
}
-----------------------------

此程序集名字:a17ce8ef9c164e558facf13425b279c6, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
此程序集是否为动态程序集:否
编译后的程序集中类的数量:4
程序集中的类分别是:EmbeddedAttribute,RefSafetyRulesAttribute,A,B
-----------脚本代码-----------
public class A
{
}
using System;

public static class B
{
    public static void Show()
    {
        Console.WriteLine("HelloWorld!");
    }
}
-----------------------------

运行方法:
HelloWorld!

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器