多语言笔记系列:Polyglot Notebooks 技巧与总结

使用技巧与总结

使用技巧

善用花括号

  • 隔离使用域
//教学或演示时,常有对比功能,代码基本相同:花括号可以使用相同的变量名而不冲突
{   //测试 where
    var source = "你 是 我的 宝儿 !".Split(" ");
    var result = source.Where(s=> s.Length<=1).Count();
    result.Display();
}

{   //测试 FirstOrDefault
    var source = "你 是 我的 宝儿 !".Split(" ");
    var result = source.FirstOrDefault(s => s != "!");
    result.Display();
}
  • 文件代码折叠
//折叠整个代码块,方便全局查看
{
    //多行业务代码





}

提取共用功能

把共用的部分独立出来,方便统一管理和引用。

  • 单独笔记文件:Nuget包导入、公共命名空间引用、共用对象、共用方法等,放入单独笔记文件,在初始化单元格统一引用
//初始化单元格:必须先执行一次
#!import "./Base.ipynb"
  • 单独的文件(C#、js等):提取公用功能到单独文件,方便统一调用
//导入文件
#!import "./shared/script/tools.cs"

//使用功能
{
    var path = Tools.GetCurrentPath();
    Console.WriteLine($"当前路径:{path}");
}

动态执行: 对只能执行一次等功能的代码可以动态执行,甚至动态添加单元格

#r "nuget:Microsoft.DotNet.Interactive.SQLite,*-*"
/*  connect 和 import 等命令,只能执行一次
    #!connect sqlite --kernel-name SQLiteSharedKernel --connection-string "Data Source=.\assets\database\study.db;"
*/

using Microsoft.DotNet.Interactive;
using Microsoft.DotNet.Interactive.Commands;

//动态方法:可执行多次,且可使用变量等功能
{
    //内核名:魔法命令中的内核名,执行后会自动加 sql- 前缀,做为内核名被使用
    string magicCommandKernelName =  "SQLiteSharedKernel";
    string completeKernelName = "sql-" + magicCommandKernelName;

    //引入内核:可重复执行
    if(Microsoft.DotNet.Interactive.Kernel.Root.FindKernelByName(completeKernelName) == null)
    {
        var connectKernelCode = $"#!connect sqlite --kernel-name {magicCommandKernelName} --connection-string \"{SharedDbConnect.SQLiteConnectionString}\"";
        await Kernel.Root.SendAsync(new SubmitCode( connectKernelCode,  "csharp"));
    }
    else
    {
        Console.WriteLine($"名为 {completeKernelName} 的内核已存在。需要新内核时,请为--kernel-name参数使用不同的值, 本次执行不做任何更改!");
    }
}
//可动态添加单元格
using Microsoft.DotNet.Interactive;
using Microsoft.DotNet.Interactive.Commands;

{//每执行一次,在下方添加代码单元格:可执行的
    var command = new SendEditableCode(
    "csharp", 
    "Console.WriteLine(\"我是动态生成的代码单元哈!\");");

    var input = await Kernel.Root.SendAsync(command);
}

Console.WriteLine("我是动态生成的代码单元哈!");

了解各种路径

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Reflection;

//查看各种程序路径
{
    var pathDic = new Dictionary<string, (string desc, string path)>() 
    {
        //当前运行的exe的完整路径,包含exe文件名,只用于WinForm
        {"Application.ExecutablePath",("程序集基完整路径(仅WinForm)", "Application.ExecutablePath 只适用于WinForm") },

        //程序的启动路径:只用于WinForm
        {"Application.StartupPath",("程序集启动路径(仅WinForm)", "Application.StartupPath 只适用于WinForm") },

        //当前执行的exe或启动项目的路径,通过AppContext
        {"AppContext.BaseDirectory",("执行或启动路径", AppContext.BaseDirectory) },  

        //当前执行的exe的目录,不包含exe名,使用AppDomain
        {"AppDomain.CurrentDomain.BaseDirectory",("程序集解析程序用于探测程序集的基目录", AppDomain.CurrentDomain.BaseDirectory) }, 

        //程序安装或启动基目录  包含应用程序的目录的名称
        {"AppDomain.CurrentDomain.SetupInformation.ApplicationBase",("程序安装或启动基目录", AppDomain.CurrentDomain.SetupInformation.ApplicationBase) }, 

        //当前进程的主模块路径,包含exe名
        {"Process.GetCurrentProcess().MainModule.FileName",("当前进程的主模块路径", Process.GetCurrentProcess()?.MainModule?.FileName) }, 

        //环境变量:用户当前工作目录的完整限定路径
        {"Environment.CurrentDirectory",("用户当前工作目录的完整限定路径", Environment.CurrentDirectory) }, 

        //环境变量:当前exe的完整路径,包含exe名,通过命令行参数
        {"Environment.GetCommandLineArgs()[0]",("当前exe的完整路径", Environment.GetCommandLineArgs()[0]) }, 

        //当前工作目录的路径(可变)
        {"Directory.GetCurrentDirectory",("当前工作目录的路径(可变)", Directory.GetCurrentDirectory()) },
        
        //当前Assembly的加载路径,包含dll或exe名
        {"Assembly.GetExecutingAssembly().Location",("当前Assembly的加载路径", Assembly.GetExecutingAssembly().Location) },

        //入口程序集的路径
        {"Assembly.GetEntryAssembly().Location",("入口程序集的路径", Assembly.GetEntryAssembly()?.Location) },

        //已过时:当前程序集的CodeBase路径,可能为file URI格式
        {"Assembly.GetExecutingAssembly().CodeBase",("当前程序集的CodeBase路径", Assembly.GetExecutingAssembly()?.CodeBase) },

        //已过时:入口程序集的CodeBase路径,可能为file URI格式
        {"Assembly.GetEntryAssembly().CodeBase",("入口程序集的CodeBase路径", Assembly.GetEntryAssembly()?.CodeBase) },
    };

    var message = string.Empty;
    foreach (var item in pathDic)
    {
        message += $"{item.Key} => {item.Value.path}{Environment.NewLine}";
    }

    Console.WriteLine(message);
}

总结

Polyglot Notebooks优点非常多,缺点也不少。有其非常适用的场景,也有其难以使用的地方。主要是用对地方,它就是神器!

优点:少说一些,文章已有说明

  • 多语言可以混合使用
  • 各语言内核之间可:共享变量
  • 图文混排,非常适合:教学场景、学习笔记场景、功能演示场景、快速验证场景等

缺点:个人总结,可能不很准确

  • 不支持调试:个人感觉是最大的缺点,不能调试代码太难受了。(虽然有一些变通的方法,但都比较难用, 增加复杂性功能也不好用);
  • 暂时不支持 .net 项目的引用:可先编译,再引用编译过的Dll和nuget包。也能蛋疼,官方说在"研究",希望能研究好吧;
  • 内置智能提示弱:功能弱、不稳定,与Visual Studio 差了百条街,甚至与VS Code本身都不是一个等级的;
  • 代码折叠与显示弱:功能太弱;

Next(下一个)

咱们CSDN视频课程见!

你可能感兴趣的:(Polyglot,Notebooks,教程,笔记,多语言笔记,Polyglot,Notebooks,C#,C#,Jupyter,jupyter)