Natasha V5.2.2.1 穩定版正式釋出.

AzulX發表於2023-04-26

DotNetCore.Natasha.CSharp v5.2.2.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() 仍然不可多次編譯, 請及時快取結果.

DotNetCore.Natasha.Domain v5.2.0.1

  • 取消 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<Action>("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 => 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!

相關文章