{ "cells": [ { "cell_type": "markdown", "id": "b42c0b7a", "metadata": {}, "source": [ "使用技巧与总结\n", "============" ] }, { "cell_type": "markdown", "id": "6a42a4a9", "metadata": {}, "source": [ "## 使用技巧" ] }, { "cell_type": "markdown", "id": "8d22d827", "metadata": {}, "source": [ "### 善用花括号" ] }, { "cell_type": "markdown", "id": "d2f12264", "metadata": {}, "source": [ "+ 隔离使用域" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/html": [ "
3
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "你" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "//教学或演示时,常有对比功能,代码基本相同:花括号可以使用相同的变量名而不冲突\n", "{ //测试 where\n", " var source = \"你 是 我的 宝儿 !\".Split(\" \");\n", " var result = source.Where(s=> s.Length<=1).Count();\n", " result.Display();\n", "}\n", "\n", "{ //测试 FirstOrDefault\n", " var source = \"你 是 我的 宝儿 !\".Split(\" \");\n", " var result = source.FirstOrDefault(s => s != \"!\");\n", " result.Display();\n", "}" ] }, { "cell_type": "markdown", "id": "fec882be", "metadata": {}, "source": [ "+ 文件代码折叠" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "//折叠整个代码块,方便全局查看\n", "{\n", " //多行业务代码\n", "\n", "\n", "\n", "\n", "\n", "}" ] }, { "cell_type": "markdown", "id": "be07ffa2", "metadata": {}, "source": [ "### 提取共用功能" ] }, { "cell_type": "markdown", "id": "5660e6f8", "metadata": {}, "source": [ "把共用的部分独立出来,方便统一管理和引用。" ] }, { "cell_type": "markdown", "id": "0e359d4a", "metadata": {}, "source": [ "+ 单独笔记文件:Nuget包导入、公共命名空间引用、共用对象、共用方法等,放入单独笔记文件,在初始化单元格统一引用" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/html": [ "
Installed Packages
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "//初始化单元格:必须先执行一次\n", "#!import \"./Base.ipynb\"" ] }, { "cell_type": "markdown", "id": "61f85ef0", "metadata": {}, "source": [ "+ 单独的文件(C#、js等):提取公用功能到单独文件,方便统一调用" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "当前路径:c:\\Users\\ruyu\\Desktop\\多语言笔记学习\\Docs\r\n" ] } ], "source": [ "//导入文件\n", "#!import \"./shared/script/tools.cs\"\n", "\n", "//使用功能\n", "{\n", " var path = Tools.GetCurrentPath();\n", " Console.WriteLine($\"当前路径:{path}\");\n", "}" ] }, { "cell_type": "markdown", "id": "cd538991", "metadata": {}, "source": [ "### 动态执行: 对只能执行一次等功能的代码可以动态执行,甚至动态添加单元格" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/html": [ "
Installed Packages
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "Loading extension script from `C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet.interactive.sqlite\\1.0.0-beta.25177.1\\interactive-extensions\\dotnet\\extension.dib`" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Query SQLite databases.\r\n", "

This extension adds support for connecting to SQLite databases using the #!connect sqlite magic command. For more information, run a cell using the #!sql magic command.

\r\n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#r \"nuget:Microsoft.DotNet.Interactive.SQLite,*-*\"" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/plain": [ "Kernel added: #!sql-SQLiteSharedKernel" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "/* connect 和 import 等命令,只能执行一次\n", " #!connect sqlite --kernel-name SQLiteSharedKernel --connection-string \"Data Source=.\\assets\\database\\study.db;\"\n", "*/\n", "\n", "using Microsoft.DotNet.Interactive;\n", "using Microsoft.DotNet.Interactive.Commands;\n", "\n", "//动态方法:可执行多次,且可使用变量等功能\n", "{\n", " //内核名:魔法命令中的内核名,执行后会自动加 sql- 前缀,做为内核名被使用\n", " string magicCommandKernelName = \"SQLiteSharedKernel\";\n", " string completeKernelName = \"sql-\" + magicCommandKernelName;\n", "\n", " //引入内核:可重复执行\n", " if(Microsoft.DotNet.Interactive.Kernel.Root.FindKernelByName(completeKernelName) == null)\n", " {\n", " var connectKernelCode = $\"#!connect sqlite --kernel-name {magicCommandKernelName} --connection-string \\\"{SharedDbConnect.SQLiteConnectionString}\\\"\";\n", " await Kernel.Root.SendAsync(new SubmitCode( connectKernelCode, \"csharp\"));\n", " }\n", " else\n", " {\n", " Console.WriteLine($\"名为 {completeKernelName} 的内核已存在。需要新内核时,请为--kernel-name参数使用不同的值, 本次执行不做任何更改!\");\n", " }\n", "}" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "//可动态添加单元格\n", "using Microsoft.DotNet.Interactive;\n", "using Microsoft.DotNet.Interactive.Commands;\n", "\n", "{//每执行一次,在下方添加代码单元格:可执行的\n", " var command = new SendEditableCode(\n", " \"csharp\", \n", " \"Console.WriteLine(\\\"我是动态生成的代码单元哈!\\\");\");\n", "\n", " var input = await Kernel.Root.SendAsync(command);\n", "}\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "Console.WriteLine(\"我是动态生成的代码单元哈!\");" ] }, { "cell_type": "markdown", "id": "333f49dd", "metadata": {}, "source": [ "### 了解各种路径" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Application.ExecutablePath => Application.ExecutablePath 只适用于WinForm\r\n", "Application.StartupPath => Application.StartupPath 只适用于WinForm\r\n", "AppContext.BaseDirectory => C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet-interactive\\1.0.617701\\tools\\net9.0\\any\\\r\n", "AppDomain.CurrentDomain.BaseDirectory => C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet-interactive\\1.0.617701\\tools\\net9.0\\any\\\r\n", "AppDomain.CurrentDomain.SetupInformation.ApplicationBase => C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet-interactive\\1.0.617701\\tools\\net9.0\\any\\\r\n", "Process.GetCurrentProcess().MainModule.FileName => C:\\Program Files\\dotnet\\dotnet.exe\r\n", "Environment.CurrentDirectory => c:\\Users\\ruyu\\Desktop\\多语言笔记学习\\Docs\r\n", "Environment.GetCommandLineArgs()[0] => C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet-interactive\\1.0.617701\\tools\\net9.0\\any\\Microsoft.DotNet.Interactive.App.dll\r\n", "Directory.GetCurrentDirectory => c:\\Users\\ruyu\\Desktop\\多语言笔记学习\\Docs\r\n", "Assembly.GetExecutingAssembly().Location => \r\n", "Assembly.GetEntryAssembly().Location => C:\\Users\\ruyu\\.nuget\\packages\\microsoft.dotnet-interactive\\1.0.617701\\tools\\net9.0\\any\\Microsoft.DotNet.Interactive.App.dll\r\n", "Assembly.GetExecutingAssembly().CodeBase => file:///C:/Program Files/dotnet/shared/Microsoft.NETCore.App/9.0.4/System.Private.CoreLib.dll\r\n", "Assembly.GetEntryAssembly().CodeBase => file:///C:/Users/ruyu/.nuget/packages/microsoft.dotnet-interactive/1.0.617701/tools/net9.0/any/Microsoft.DotNet.Interactive.App.dll\r\n", "\r\n" ] } ], "source": [ "using System;\n", "using System.IO;\n", "using System.Threading;\n", "using System.Threading.Tasks;\n", "using System.Diagnostics;\n", "using System.Reflection;\n", "\n", "//查看各种程序路径\n", "{\n", " var pathDic = new Dictionary() \n", " {\n", " //当前运行的exe的完整路径,包含exe文件名,只用于WinForm\n", " {\"Application.ExecutablePath\",(\"程序集基完整路径(仅WinForm)\", \"Application.ExecutablePath 只适用于WinForm\") },\n", "\n", " //程序的启动路径:只用于WinForm\n", " {\"Application.StartupPath\",(\"程序集启动路径(仅WinForm)\", \"Application.StartupPath 只适用于WinForm\") },\n", "\n", " //当前执行的exe或启动项目的路径,通过AppContext\n", " {\"AppContext.BaseDirectory\",(\"执行或启动路径\", AppContext.BaseDirectory) }, \n", "\n", " //当前执行的exe的目录,不包含exe名,使用AppDomain\n", " {\"AppDomain.CurrentDomain.BaseDirectory\",(\"程序集解析程序用于探测程序集的基目录\", AppDomain.CurrentDomain.BaseDirectory) }, \n", "\n", " //程序安装或启动基目录 包含应用程序的目录的名称\n", " {\"AppDomain.CurrentDomain.SetupInformation.ApplicationBase\",(\"程序安装或启动基目录\", AppDomain.CurrentDomain.SetupInformation.ApplicationBase) }, \n", "\n", " //当前进程的主模块路径,包含exe名\n", " {\"Process.GetCurrentProcess().MainModule.FileName\",(\"当前进程的主模块路径\", Process.GetCurrentProcess()?.MainModule?.FileName) }, \n", "\n", " //环境变量:用户当前工作目录的完整限定路径\n", " {\"Environment.CurrentDirectory\",(\"用户当前工作目录的完整限定路径\", Environment.CurrentDirectory) }, \n", "\n", " //环境变量:当前exe的完整路径,包含exe名,通过命令行参数\n", " {\"Environment.GetCommandLineArgs()[0]\",(\"当前exe的完整路径\", Environment.GetCommandLineArgs()[0]) }, \n", "\n", " //当前工作目录的路径(可变)\n", " {\"Directory.GetCurrentDirectory\",(\"当前工作目录的路径(可变)\", Directory.GetCurrentDirectory()) },\n", " \n", " //当前Assembly的加载路径,包含dll或exe名\n", " {\"Assembly.GetExecutingAssembly().Location\",(\"当前Assembly的加载路径\", Assembly.GetExecutingAssembly().Location) },\n", "\n", " //入口程序集的路径\n", " {\"Assembly.GetEntryAssembly().Location\",(\"入口程序集的路径\", Assembly.GetEntryAssembly()?.Location) },\n", "\n", " //已过时:当前程序集的CodeBase路径,可能为file URI格式\n", " {\"Assembly.GetExecutingAssembly().CodeBase\",(\"当前程序集的CodeBase路径\", Assembly.GetExecutingAssembly()?.CodeBase) },\n", "\n", " //已过时:入口程序集的CodeBase路径,可能为file URI格式\n", " {\"Assembly.GetEntryAssembly().CodeBase\",(\"入口程序集的CodeBase路径\", Assembly.GetEntryAssembly()?.CodeBase) },\n", " };\n", "\n", " var message = string.Empty;\n", " foreach (var item in pathDic)\n", " {\n", " message += $\"{item.Key} => {item.Value.path}{Environment.NewLine}\";\n", " }\n", "\n", " Console.WriteLine(message);\n", "}" ] }, { "cell_type": "markdown", "id": "8e37e66e", "metadata": {}, "source": [ "## 总结" ] }, { "cell_type": "markdown", "id": "913992ad", "metadata": {}, "source": [ "Polyglot Notebooks优点非常多,缺点也不少。有其非常适用的场景,也有其难以使用的地方。主要是用对地方,它就是神器!" ] }, { "cell_type": "markdown", "id": "c01fc2fb", "metadata": {}, "source": [ "### 优点:少说一些,文章已有说明" ] }, { "cell_type": "markdown", "id": "b89044dd", "metadata": {}, "source": [ "+ 多语言可以混合使用\n", "+ 各语言内核之间可:共享变量\n", "+ 图文混排,非常适合:教学场景、学习笔记场景、功能演示场景、快速验证场景等" ] }, { "cell_type": "markdown", "id": "2d5c8cfe", "metadata": {}, "source": [ "### 缺点:个人总结,可能不很准确" ] }, { "cell_type": "markdown", "metadata": { "polyglot_notebook": { "kernelName": "csharp" } }, "source": [ "+ 不支持调试:个人感觉是最大的缺点,不能调试代码太难受了。(虽然有一些变通的方法,但都比较难用, 增加复杂性功能也不好用);\n", "+ 暂时不支持 .net 项目的引用:可先编译,再引用编译过的Dll和nuget包。也能蛋疼,官方说在\"研究\",希望能研究好吧;\n", "+ 内置智能提示弱:功能弱、不稳定,与Visual Studio 差了百条街,甚至与VS Code本身都不是一个等级的; \n", "+ 代码折叠与显示弱:功能太弱;" ] }, { "cell_type": "markdown", "id": "b368390b", "metadata": {}, "source": [ "## Next(下一个)\n", "\n", "咱们CSDN视频课程见!" ] } ], "metadata": { "kernelspec": { "display_name": ".NET (C#)", "language": "C#", "name": ".net-csharp" }, "language_info": { "name": "polyglot-notebook" }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [], "languageName": "csharp", "name": "csharp" }, { "aliases": [], "languageName": "SQLite", "name": "sql-SQLiteSharedKernel" } ] } } }, "nbformat": 4, "nbformat_minor": 5 }