Files
blog/posts/e9a8e898/index.html
T
2026-06-19 13:28:19 +08:00

797 lines
62 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="这篇文章通过Rectangle示例讲解C#面向对象基础,展示类与对象如何封装数据及行为,并输出面积15.75。随后介绍using引入命名空间、class声明类、注释、成员变量与函数、实例化流程及标识符规则。重点解析C#9顶级语句,无需Main方法即可在文件顶层直接写代码,编译器自动生成入口,适合脚本化开发,示例演示变量、方法、LINQ与异常处理,简化小型项目结构。"><link rel="icon" href="/images/Bi.ico"><script defer src="https://umami.biss.click/script.js" data-website-id="3d97b310-b241-4fc6-bc9c-68e317fc7d42"></script><script>window.SITE_CONFIG = {"site":{"url":"https://blog.biss.click","name":"Bi's Blog","description":"Personal blog by biss.","language":"zh-CN","domain":"blog.biss.click","slogan":"好奇心转化为代码的空间。","startTime":"2025-01-01T00:00:00+08:00","copyrightStartYear":2025,"license":"内容采用 CC BY-NC-SA 4.0 协议"},"author":{"name":"biss","email":"bishsh2006@gmail.com","github":"https://github.com/bishshi","avatar":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"comments":{"envId":"https://comment.biss.click","region":"","script":"https://cdn.jsdelivr.net/npm/twikoo@1.7.7/dist/twikoo.min.js"},"analytics":{"umami":{"script":"https://umami.biss.click/script.js","websiteId":"3d97b310-b241-4fc6-bc9c-68e317fc7d42","statsEndpoint":"https://blogumami.biss.click"}},"talks":{"apiUrl":"https://mm.biss.click/api/echo/page","pageSize":30,"homeLimit":6,"cacheKey":"talksCache","cacheTimeKey":"talksCacheTime","cacheDurationMs":1800000,"fallbackAvatar":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"search":{"apiKey":"2uxQzk7eD2GBCljdSmIiuU3ause7UK9n","server":{"host":"typesense.biss.click","port":"443","protocol":"https"},"indexName":"blogs","searchParams":{"query_by":"title,content","highlight_full_fields":"title,content","per_page":8,"num_typos":1,"typo_tokens_threshold":1,"prefix":true},"ui":{"maxRetries":10,"retryDelay":100,"animationDuration":300,"maxInitRetries":30,"placeholder":"输入关键词寻找故事..."}},"externalLinks":{"waitSeconds":10,"whitelist":["blog.biss.click","biss.click","github.com","localhost","127.0.0.1"]}};</script><script>
(() => {
const storageKey = 'site-theme';
const savedTheme = localStorage.getItem(storageKey);
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
document.documentElement.dataset.theme = savedTheme || systemTheme;
})();
</script><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/instantsearch.css/themes/reset-min.css"><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css"><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/@fortawesome/fontawesome-free@6.7.2/css/all.min.css"><title>C# 基本语法 | Bi&#39;s Blog</title><link rel="stylesheet" href="/_astro/BaseLayout.D7kFxpxP.css"></head> <body> <header class="site-header"> <nav class="nav"> <a class="brand" href="/">Bi&#39;s Blog</a> <button class="nav-menu-toggle" type="button" aria-label="打开菜单" aria-expanded="false" data-nav-toggle> <i class="fa-solid fa-bars nav-menu-open" aria-hidden="true"></i> <i class="fa-solid fa-xmark nav-menu-close" aria-hidden="true"></i> </button> <div class="nav-menu" data-nav-menu> <div class="nav-links nav-center"> <a href="/archives/"><i class="fa-solid fa-box-archive nav-icon" aria-hidden="true"></i><span>归档</span></a><a href="/categories/"><i class="fa-solid fa-folder-open nav-icon" aria-hidden="true"></i><span>分类</span></a><a href="/tags/"><i class="fa-solid fa-tags nav-icon" aria-hidden="true"></i><span>标签</span></a><a href="/shuoshuo/"><i class="fa-regular fa-comments nav-icon" aria-hidden="true"></i><span>说说</span></a><a href="/about/"><i class="fa-solid fa-heart nav-icon" aria-hidden="true"></i><span>关于</span></a><a href="/link/"><i class="fa-solid fa-link nav-icon" aria-hidden="true"></i><span>友链</span></a> </div> <div class="nav-links nav-actions"> <button class="nav-random" type="button" onclick="randomPost()" aria-label="前往随机文章" title="前往随机文章"> <i class="fa-solid fa-shuffle nav-icon" aria-hidden="true"></i> <span>随机文章</span> </button> <button class="nav-search search-typesense-trigger" type="button" aria-label="搜索" title="搜索"> <i class="fa-solid fa-magnifying-glass nav-icon" aria-hidden="true"></i> <span>搜索</span> </button> <button class="theme-toggle" type="button" aria-label="切换夜间模式" title="切换夜间模式" data-theme-toggle> <i class="fa-solid fa-sun theme-toggle-sun nav-icon" aria-hidden="true"></i> <i class="fa-solid fa-moon theme-toggle-moon nav-icon" aria-hidden="true"></i> </button> </div> </div> </nav> </header> <main> <section class="post-layout"> <article class="article post-article"> <header class="article-header"> <div class="article-header-content"> <time datetime="2025-08-16T18:01:10.000Z">2025/08/17</time> <h1>C# 基本语法</h1> <div class="meta-list"> <a href="/categories/study/">学习</a> <a href="/tags/C%23/">#C#</a> </div> </div> </header> <section class="article-summary-card" aria-label="AI 文章摘要"> <div class="article-summary-dots" aria-hidden="true"> <span></span> <span></span> <span></span> </div> <p class="article-summary-content"> <span class="article-summary-text" data-summary-text="这篇文章通过Rectangle示例讲解C#面向对象基础,展示类与对象如何封装数据及行为,并输出面积15.75。随后介绍using引入命名空间、class声明类、注释、成员变量与函数、实例化流程及标识符规则。重点解析C#9顶级语句,无需Main方法即可在文件顶层直接写代码,编译器自动生成入口,适合脚本化开发,示例演示变量、方法、LINQ与异常处理,简化小型项目结构。">这篇文章通过Rectangle示例讲解C#面向对象基础,展示类与对象如何封装数据及行为,并输出面积15.75。随后介绍using引入命名空间、class声明类、注释、成员变量与函数、实例化流程及标识符规则。重点解析C#9顶级语句,无需Main方法即可在文件顶层直接写代码,编译器自动生成入口,适合脚本化开发,示例演示变量、方法、LINQ与异常处理,简化小型项目结构。</span> <span class="article-summary-caret" aria-hidden="true"></span> </p> <div class="article-summary-footer"> <span class="article-summary-brand"> <span aria-hidden="true"></span>
AI摘要
</span> <span class="article-summary-model">QWEN</span> </div> </section> <div class="prose" data-toc="[{&quot;depth&quot;:1,&quot;text&quot;:&quot;简介&quot;,&quot;id&quot;:&quot;简介&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;using 关键字&quot;,&quot;id&quot;:&quot;using-关键字&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;class 关键字&quot;,&quot;id&quot;:&quot;class-关键字&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;C# 中的注释&quot;,&quot;id&quot;:&quot;c-中的注释&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;成员变量&quot;,&quot;id&quot;:&quot;成员变量&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;标识符&quot;,&quot;id&quot;:&quot;标识符&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;C# 关键字&quot;,&quot;id&quot;:&quot;c-关键字&quot;},{&quot;depth&quot;:1,&quot;text&quot;:&quot;顶级语句(Top-Level Statements&quot;,&quot;id&quot;:&quot;顶级语句top-level-statements&quot;},{&quot;depth&quot;:2,&quot;text&quot;:&quot;特点:&quot;,&quot;id&quot;:&quot;特点&quot;}]"> <h1 id="简介">简介</h1>
<p>C# 是一种面向对象的编程语言。在面向对象的程序设计方法中,程序由各种相互交互的对象组成。相同种类的对象通常具有相同的类型,或者说,是在相同的 class 中。</p>
<p>例如,以 Rectangle(矩形)对象为例。它具有 length 和 width 属性。根据设计,它可能需要接受这些属性值、计算面积和显示细节。</p>
<p>实例</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="c"><code><span class="line"><span style="color:#E1E4E8">using System;</span></span>
<span class="line"><span style="color:#E1E4E8">namespace RectangleApplication</span></span>
<span class="line"><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#E1E4E8"> class Rectangle</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#6A737D"> // 成员变量</span></span>
<span class="line"><span style="color:#F97583"> double</span><span style="color:#E1E4E8"> length;</span></span>
<span class="line"><span style="color:#F97583"> double</span><span style="color:#E1E4E8"> width;</span></span>
<span class="line"><span style="color:#E1E4E8"> public </span><span style="color:#F97583">void</span><span style="color:#B392F0"> Acceptdetails</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> length </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 4.5</span><span style="color:#E1E4E8">; </span></span>
<span class="line"><span style="color:#E1E4E8"> width </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 3.5</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> public </span><span style="color:#F97583">double</span><span style="color:#B392F0"> GetArea</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> return</span><span style="color:#E1E4E8"> length </span><span style="color:#F97583">*</span><span style="color:#E1E4E8"> width;</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> public </span><span style="color:#F97583">void</span><span style="color:#B392F0"> Display</span><span style="color:#E1E4E8">()</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Length: {0}"</span><span style="color:#E1E4E8">, length);</span></span>
<span class="line"><span style="color:#E1E4E8"> Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Width: {0}"</span><span style="color:#E1E4E8">, width);</span></span>
<span class="line"><span style="color:#E1E4E8"> Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Area: {0}"</span><span style="color:#E1E4E8">, </span><span style="color:#B392F0">GetArea</span><span style="color:#E1E4E8">());</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> </span></span>
<span class="line"><span style="color:#E1E4E8"> class ExecuteRectangle</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> static</span><span style="color:#F97583"> void</span><span style="color:#B392F0"> Main</span><span style="color:#E1E4E8">(string</span><span style="color:#F97583">[]</span><span style="color:#E1E4E8"> args)</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> Rectangle r </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> new </span><span style="color:#B392F0">Rectangle</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> r.</span><span style="color:#B392F0">Acceptdetails</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> r.</span><span style="color:#B392F0">Display</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> Console.</span><span style="color:#B392F0">ReadLine</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre>
<p>尝试一下 »
当上面的代码被编译和执行时,它会产生下列结果:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="plaintext"><code><span class="line"><span>Length: 4.5</span></span>
<span class="line"><span>Width: 3.5</span></span>
<span class="line"><span>Area: 15.75</span></span></code></pre>
<h1 id="using-关键字">using 关键字</h1>
<p>在任何 C# 程序中的第一条语句都是:</p>
<p>using System;
using 关键字用于在程序中包含命名空间。一个程序可以包含多个 using 语句。</p>
<h1 id="class-关键字">class 关键字</h1>
<p>class 关键字用于声明一个类。</p>
<h1 id="c-中的注释">C# 中的注释</h1>
<p>注释是用于解释代码。编译器会忽略注释的条目。在 C# 程序中,多行注释以 /* 开始,并以字符 */ 终止,如下所示:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="c"><code><span class="line"><span style="color:#6A737D">/* 这个程序演示</span></span>
<span class="line"><span style="color:#6A737D">C# 的注释</span></span>
<span class="line"><span style="color:#6A737D">使用 */</span></span></code></pre>
<p>单行注释是用 // 符号表示。例如:</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="c"><code><span class="line"><span style="color:#6A737D">// 这一行是注释 </span></span></code></pre>
<h1 id="成员变量">成员变量</h1>
<p>变量是类的属性或数据成员,用于存储数据。在上面的程序中,Rectangle 类有两个成员变量,名为 length 和 width。</p>
<p>成员函数
函数是一系列执行指定任务的语句。类的成员函数是在类内声明的。我们举例的类 Rectangle 包含了三个成员函数: AcceptDetails、GetArea 和 Display。</p>
<p>实例化一个类
在上面的程序中,类 ExecuteRectangle 是一个包含 Main() 方法和实例化 Rectangle 类的类。</p>
<h1 id="标识符">标识符</h1>
<p>标识符是用来识别类、变量、函数或任何其它用户定义的项目。在 C# 中,类的命名必须遵循如下基本规则:</p>
<ul>
<li>标识符必须以字母、下划线或 @ 开头,后面可以跟一系列的字母、数字( 0 - 9 )、下划线( _ )、@。</li>
<li>标识符中的第一个字符不能是数字。</li>
<li>标识符必须不包含任何嵌入的空格或符号,比如 ? - +! # % ^ &#x26; * ( ) [ ] { } . ; : ” / \。</li>
<li>标识符不能是 C# 关键字。除非它们有一个 @ 前缀。 例如,@if 是有效的标识符,但 if 不是,因为 if 是关键字。</li>
<li>标识符必须区分大小写。大写字母和小写字母被认为是不同的字母。</li>
<li>不能与C#的类库名称相同。</li>
</ul>
<h1 id="c-关键字">C# 关键字</h1>
<p>关键字是 C# 编译器预定义的保留字。这些关键字不能用作标识符,但是,如果您想使用这些关键字作为标识符,可以在关键字前面加上 @ 字符作为前缀。</p>
<p>在 C# 中,有些关键字在代码的上下文中有特殊的意义,如 get 和 set,这些被称为上下文关键字(contextual keywords)。</p>
<h1 id="顶级语句top-level-statements">顶级语句(Top-Level Statements</h1>
<p>在 C# 9.0 版本中,引入了顶级语句(Top-Level Statements)的概念,这是一种新的编程范式,允许开发者在文件的顶层直接编写语句,而不需要将它们封装在方法或类中。</p>
<h2 id="特点">特点:</h2>
<p>无需类或方法:顶级语句允许你直接在文件的顶层编写代码,无需定义类或方法。</p>
<p>文件作为入口点:包含顶级语句的文件被视为程序的入口点,类似于 C# 之前的 Main 方法。</p>
<p>自动 Main 方法:编译器会自动生成一个 Main 方法,并将顶级语句作为 Main 方法的主体。</p>
<p>支持局部函数:尽管不需要定义类,但顶级语句的文件中仍然可以定义局部函数。</p>
<p>更好的可读性:对于简单的脚本或工具,顶级语句提供了更好的可读性和简洁性。</p>
<p>适用于小型项目:顶级语句非常适合小型项目或脚本,可以快速编写和运行代码。</p>
<p>与现有代码兼容:顶级语句可以与现有的 C# 代码库一起使用,不会影响现有代码。</p>
<p>传统 C# 代码 - 在使用顶级语句之前,你必须像这样编写一个 C# 程序:</p>
<p>实例</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="c"><code><span class="line"><span style="color:#E1E4E8">using System;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8">namespace MyApp</span></span>
<span class="line"><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#E1E4E8"> class Program</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#F97583"> static</span><span style="color:#F97583"> void</span><span style="color:#B392F0"> Main</span><span style="color:#E1E4E8">(string</span><span style="color:#F97583">[]</span><span style="color:#E1E4E8"> args)</span></span>
<span class="line"><span style="color:#E1E4E8"> {</span></span>
<span class="line"><span style="color:#E1E4E8"> Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Hello, World!"</span><span style="color:#E1E4E8">);</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8"> }</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre>
<p>使用顶级语句的 C# 代码 - 使用顶级语句,可以简化为:</p>
<p>实例</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="c"><code><span class="line"><span style="color:#E1E4E8">using System;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E1E4E8">Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Hello, World!"</span><span style="color:#E1E4E8">);</span></span></code></pre>
<p>顶级语句支持所有常见的 C# 语法,包括声明变量、定义方法、处理异常等。</p>
<p>实例</p>
<pre class="astro-code github-dark" style="background-color:#24292e;color:#e1e4e8; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;" tabindex="0" data-language="c"><code><span class="line"><span style="color:#E1E4E8">using System;</span></span>
<span class="line"><span style="color:#E1E4E8">using System.Linq;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// 顶级语句中的变量声明</span></span>
<span class="line"><span style="color:#F97583">int</span><span style="color:#E1E4E8"> number </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 42</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#E1E4E8">string message </span><span style="color:#F97583">=</span><span style="color:#9ECBFF"> "The answer to life, the universe, and everything is"</span><span style="color:#E1E4E8">;</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// 输出变量</span></span>
<span class="line"><span style="color:#E1E4E8">Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">($</span><span style="color:#9ECBFF">"{message} {number}."</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// 定义和调用方法</span></span>
<span class="line"><span style="color:#F97583">int</span><span style="color:#B392F0"> Add</span><span style="color:#E1E4E8">(</span><span style="color:#F97583">int</span><span style="color:#FFAB70"> a</span><span style="color:#E1E4E8">, </span><span style="color:#F97583">int</span><span style="color:#FFAB70"> b</span><span style="color:#E1E4E8">) </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> a </span><span style="color:#F97583">+</span><span style="color:#E1E4E8"> b;</span></span>
<span class="line"><span style="color:#E1E4E8">Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">($</span><span style="color:#9ECBFF">"Sum of 1 and 2 is {Add(1, 2)}."</span><span style="color:#E1E4E8">);</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// 使用 LINQ</span></span>
<span class="line"><span style="color:#E1E4E8">var numbers </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> new</span><span style="color:#F97583">[]</span><span style="color:#E1E4E8"> { </span><span style="color:#79B8FF">1</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">2</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">3</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">4</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">5</span><span style="color:#E1E4E8"> };</span></span>
<span class="line"><span style="color:#E1E4E8">var evens </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> numbers.</span><span style="color:#B392F0">Where</span><span style="color:#E1E4E8">(n </span><span style="color:#F97583">=></span><span style="color:#E1E4E8"> n </span><span style="color:#F97583">%</span><span style="color:#79B8FF"> 2</span><span style="color:#F97583"> ==</span><span style="color:#79B8FF"> 0</span><span style="color:#E1E4E8">).</span><span style="color:#B392F0">ToArray</span><span style="color:#E1E4E8">();</span></span>
<span class="line"><span style="color:#E1E4E8">Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Even numbers: "</span><span style="color:#F97583"> +</span><span style="color:#E1E4E8"> string.</span><span style="color:#B392F0">Join</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">", "</span><span style="color:#E1E4E8">, evens));</span></span>
<span class="line"></span>
<span class="line"><span style="color:#6A737D">// 异常处理</span></span>
<span class="line"><span style="color:#E1E4E8">try</span></span>
<span class="line"><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#F97583"> int</span><span style="color:#E1E4E8"> zero </span><span style="color:#F97583">=</span><span style="color:#79B8FF"> 0</span><span style="color:#E1E4E8">;</span></span>
<span class="line"><span style="color:#F97583"> int</span><span style="color:#E1E4E8"> result </span><span style="color:#F97583">=</span><span style="color:#E1E4E8"> number </span><span style="color:#F97583">/</span><span style="color:#E1E4E8"> zero;</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span>
<span class="line"><span style="color:#E1E4E8">catch (DivideByZeroException ex)</span></span>
<span class="line"><span style="color:#E1E4E8">{</span></span>
<span class="line"><span style="color:#E1E4E8"> Console.</span><span style="color:#B392F0">WriteLine</span><span style="color:#E1E4E8">(</span><span style="color:#9ECBFF">"Error: "</span><span style="color:#F97583"> +</span><span style="color:#E1E4E8"> ex.Message);</span></span>
<span class="line"><span style="color:#E1E4E8">}</span></span></code></pre> </div> <section class="post-copyright-card" aria-label="文章版权信息"> <div class="post-copyright-mark" aria-hidden="true"> <span>CC</span> </div> <div class="post-copyright-main"> <h2>C# 基本语法</h2> <a class="post-copyright-link" href="/posts/e9a8e898/">/posts/e9a8e898/</a> <dl class="post-copyright-meta"> <div> <dt>作者</dt> <dd>biss</dd> </div> <div> <dt>发布于</dt> <dd><time datetime="2025-08-16T18:01:10.000Z">2025/08/17</time></dd> </div> <div> <dt>许可协议</dt> <dd><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noreferrer">CC BY-NC-SA 4.0</a></dd> </div> </dl> </div> <div class="post-copyright-footer"> <div class="post-copyright-tags" aria-label="文章标签"> <a href="/tags/C%23/">C#</a> </div> <div class="post-copyright-actions" aria-label="文章操作"> <button class="post-copyright-action is-primary post-share-button" type="button" data-share-title="C# 基本语法" data-share-url="https://blog.biss.click/posts/e9a8e898/" title="分享文章"> <svg aria-hidden="true" viewBox="0 0 24 24"> <path d="M4 12v7a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-7"></path> <path d="M12 16V4"></path> <path d="m7 9 5-5 5 5"></path> </svg> <span>分享</span> </button> <a class="post-copyright-action" href="/rss.xml" title="订阅 RSS"> <svg aria-hidden="true" viewBox="0 0 24 24"> <path d="M5 5a14 14 0 0 1 14 14"></path> <path d="M5 11a8 8 0 0 1 8 8"></path> <path d="M6 18h.01"></path> </svg> <span>订阅</span> </a> <a class="post-copyright-action" href="/about/" title="打赏作者"> <svg aria-hidden="true" viewBox="0 0 24 24"> <path d="M7 8h10"></path> <path d="M8 8V5h8v3"></path> <path d="M6 8h12l-1.5 11h-9L6 8Z"></path> <path d="M10 12h4"></path> </svg> <span>打赏</span> </a> <a class="post-copyright-icon" href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fblog.biss.click%2Fposts%2Fe9a8e898%2F&amp;text=C%23%20%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95" target="_blank" rel="noreferrer" title="分享到 X"> <span aria-hidden="true">x</span> </a> <a class="post-copyright-icon" href="https://service.weibo.com/share/share.php?url=https%3A%2F%2Fblog.biss.click%2Fposts%2Fe9a8e898%2F&amp;title=C%23%20%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95" target="_blank" rel="noreferrer" title="分享到微博"> <span aria-hidden="true"></span> </a> </div> </div> </section> <script>
(() => {
document.querySelectorAll('.post-share-button').forEach((button) => {
button.addEventListener('click', async () => {
const title = button.dataset.shareTitle || document.title;
const url = button.dataset.shareUrl || window.location.href;
const label = button.querySelector('span');
const originalText = label?.textContent || '分享';
try {
if (navigator.share) {
await navigator.share({ title, url });
return;
}
await navigator.clipboard.writeText(url);
if (label) label.textContent = '已复制';
} catch {
if (label) label.textContent = '复制失败';
} finally {
window.setTimeout(() => {
if (label) label.textContent = originalText;
}, 1800);
}
});
});
})();
</script> <section id="post-comment" class="twikoo-comments" aria-label="Comments" data-env-id="https://comment.biss.click" data-region data-path="/posts/e9a8e898/" data-script="https://cdn.jsdelivr.net/npm/twikoo@1.7.7/dist/twikoo.min.js"> <div class="twikoo-comments-head"> <span class="twikoo-comments-icon" aria-hidden="true"> <svg viewBox="0 0 24 24"> <path d="M21 12a8 8 0 0 1-8 8H7l-4 3v-5a8 8 0 1 1 18-6Z"></path> </svg> </span> <div> <h2>Comments</h2> <p>C# 基本语法</p> </div> </div> <div id="twikoo-wrap" class="twikoo-wrap"></div> </section> <script>
(() => {
const root = document.getElementById('post-comment');
const wrap = document.getElementById('twikoo-wrap');
if (!root || !wrap || root.dataset.twikooLoaded === 'true') return;
const envId = root.dataset.envId;
const path = root.dataset.path || window.location.pathname;
const region = root.dataset.region || undefined;
if (!envId) return;
root.dataset.twikooLoaded = 'true';
const initTwikoo = () => {
if (!window.twikoo || typeof window.twikoo.init !== 'function') return;
window.twikoo.init({
el: wrap,
envId,
region,
path,
});
};
if (window.twikoo) {
initTwikoo();
return;
}
const script = document.createElement('script');
script.src = root.dataset.script;
script.defer = true;
script.onload = initTwikoo;
script.onerror = () => {
root.dataset.twikooLoaded = 'false';
};
document.head.appendChild(script);
})();
</script> </article> <aside class="article-sidebar" aria-label="文章侧边栏"> <section class="sidebar-card article-author-card"> <img class="profile-avatar" src="https://free.picui.cn/free/2025/08/10/689845496a283.png" alt="biss" loading="lazy"> <div class="profile-name">biss</div> <div class="article-author-meta"> <span>2025/08/17</span> <a href="/categories/study/">学习</a> </div> </section> <section class="sidebar-card article-tags-card"> <h2> <span aria-hidden="true">#</span>
文章标签
<em>1</em> </h2> <div class="article-tag-list" aria-label="文章标签"> <a href="/tags/C%23/">#C#</a> </div> </section> <div class="article-sticky-sidebar"> <section class="sidebar-card toc-card"> <h2> <span aria-hidden="true"></span>
文章目录
<em>9</em> </h2> <nav class="toc-list toc-tree" aria-label="文章目录" data-toc-tree> <div class="toc-group is-open" data-toc-group data-heading-id="简介"> <a class="toc-link toc-link-main" href="#简介" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>简介</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="using-关键字"> <a class="toc-link toc-link-main" href="#using-关键字" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>using 关键字</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="class-关键字"> <a class="toc-link toc-link-main" href="#class-关键字" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>class 关键字</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="c-中的注释"> <a class="toc-link toc-link-main" href="#c-中的注释" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>C# 中的注释</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="成员变量"> <a class="toc-link toc-link-main" href="#成员变量" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>成员变量</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="标识符"> <a class="toc-link toc-link-main" href="#标识符" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>标识符</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="c-关键字"> <a class="toc-link toc-link-main" href="#c-关键字" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>C# 关键字</span> </a> </div><div class="toc-group" data-toc-group data-heading-id="顶级语句top-level-statements"> <a class="toc-link toc-link-main" href="#顶级语句top-level-statements" data-toc-link data-toc-top> <span class="toc-marker" aria-hidden="true"></span> <span>顶级语句(Top-Level Statements</span> </a> <div class="toc-children" data-toc-children> <a class="toc-link toc-link-child toc-depth-2" href="#特点" data-toc-link> <span>特点:</span> </a> </div> </div> </nav> </section> <section class="sidebar-card same-category-card"> <h2> <span aria-hidden="true"></span>
同类文章
<em>6</em> </h2> <div class="same-category-list"> <a href="/posts/9b2ef00a/"> <strong>OpenGL- Cohen-Sutherland 编码裁剪算法</strong> <time datetime="2026-04-15T19:34:23.000Z">2026/04/16</time> </a><a href="/posts/7207243b/"> <strong>OpenGL-直线的扫描转换</strong> <time datetime="2026-04-11T19:01:02.000Z">2026/04/12</time> </a><a href="/posts/437a5198/"> <strong>OpenGL-基础程序</strong> <time datetime="2026-04-11T18:20:34.000Z">2026/04/12</time> </a><a href="/posts/c4477b0c/"> <strong>配置OpenGL环境</strong> <time datetime="2026-04-02T04:52:16.000Z">2026/04/02</time> </a><a href="/posts/bc56f789/"> <strong>C# 入门</strong> <time datetime="2025-08-15T09:56:17.000Z">2025/08/15</time> </a><a href="/posts/f0a1a1f4/"> <strong>英语文章分享-去奋力生活吧,就好像死亡近在咫尺</strong> <time datetime="2025-08-11T20:59:46.000Z">2025/08/12</time> </a> </div> </section> <section class="sidebar-card site-info-card" data-site-info-card data-stats-endpoint="https://blogumami.biss.click"> <h2><i class="fa-solid fa-chart-line" aria-hidden="true"></i> 网站信息</h2> <dl class="site-info-list"> <div> <dt>文章数目</dt> <dd>43</dd> </div><div> <dt>本站总字数</dt> <dd>32,569</dd> </div><div> <dt>本站访客数</dt> <dd data-stat-key="visitors">--</dd> </div><div> <dt>本站访问量</dt> <dd data-stat-key="pageviews">--</dd> </div><div> <dt>最后更新时间</dt> <dd>2026/06/19</dd> </div> </dl> </section> <script>
(() => {
const cacheDuration = 10 * 60 * 1000;
const formatter = new Intl.NumberFormat('en-US');
const cards = [...document.querySelectorAll('[data-site-info-card]')];
const endpoint = cards.find((card) => card.dataset.statsEndpoint)?.dataset.statsEndpoint;
if (!endpoint) return;
const cacheKey = `site-info-stats:${endpoint}`;
const updateCards = (stats) => {
const visitors = Number(stats?.visitors);
const pageviews = Number(stats?.pageviews);
cards.forEach((card) => {
const visitorsEl = card.querySelector('[data-stat-key="visitors"]');
const pageviewsEl = card.querySelector('[data-stat-key="pageviews"]');
if (visitorsEl && Number.isFinite(visitors)) visitorsEl.textContent = formatter.format(visitors);
if (pageviewsEl && Number.isFinite(pageviews)) pageviewsEl.textContent = formatter.format(pageviews);
});
};
try {
const cached = JSON.parse(localStorage.getItem(cacheKey) || 'null');
if (cached?.time && Date.now() - cached.time < cacheDuration) {
updateCards(cached.data);
return;
}
} catch {
localStorage.removeItem(cacheKey);
}
fetch(endpoint, { headers: { Accept: 'application/json' } })
.then((response) => {
if (!response.ok) throw new Error(`Stats request failed: ${response.status}`);
return response.json();
})
.then((data) => {
localStorage.setItem(cacheKey, JSON.stringify({ time: Date.now(), data }));
updateCards(data);
})
.catch(() => {
});
})();
</script> </div> </aside> </section> </main> <footer class="site-footer" aria-label="站点页脚"> <div class="footer-inner"> <section class="footer-top" aria-label="站点信息"> <a class="footer-brand" href="/" aria-label="Bi's Blog 首页"> <img src="/images/Bi.ico" alt="" loading="lazy"> <span>Bi&#39;s Blog</span> </a> <p class="footer-slogan">好奇心转化为代码的空间。</p> </section> <section class="footer-contact" aria-label="联系方式"> <p>联系方式</p> <div class="footer-socials"> <a href="mailto:bishsh2006@gmail.com" aria-label="发送邮件" title="发送邮件"> <i class="fa-solid fa-envelope" aria-hidden="true"></i> </a><a href="/rss.xml" aria-label="订阅 RSS" title="订阅 RSS"> <i class="fa-solid fa-rss" aria-hidden="true"></i> </a><a href="https://github.com/bishshi" target="_blank" rel="noreferrer" aria-label="GitHub" title="GitHub"> <i class="fa-brands fa-github" aria-hidden="true"></i> </a> </div> <nav class="footer-contact-links" aria-label="页脚链接"> <a href="/archives/">发展历程</a> <span aria-hidden="true">|</span><a href="/privacy/">隐私政策</a> </nav> </section> <section class="footer-bottom" aria-label="版权信息"> <div> <p>© 2025 - 2026 Bi&#39;s Blog</p> <p>blog.biss.click | 内容采用 CC BY-NC-SA 4.0 协议</p> </div> <div class="footer-meta"> <p>本站已运行:<span id="site-runtime">计算中...</span></p> <p> <a href="https://fastly.com/" target="_blank" rel="noreferrer">Fastly</a> <span aria-hidden="true">|</span><a href="https://astro.build/" target="_blank" rel="noreferrer">ASTRO</a> </p> </div> </section> </div> </footer> <aside class="hitokoto-card" aria-label="一言" data-hitokoto-card data-astro-cid-4cgfuthx> <div class="hitokoto-card__head" data-astro-cid-4cgfuthx> <button class="hitokoto-card__toggle" type="button" aria-label="展开一言" aria-expanded="true" title="一言" data-hitokoto-toggle data-astro-cid-4cgfuthx> <i class="fa-solid fa-quote-left" aria-hidden="true" data-astro-cid-4cgfuthx></i> <span data-astro-cid-4cgfuthx>一言</span> </button> <div class="hitokoto-card__actions" data-astro-cid-4cgfuthx> <button class="hitokoto-card__refresh" type="button" aria-label="换一句" title="换一句" data-hitokoto-refresh data-astro-cid-4cgfuthx> <i class="fa-solid fa-rotate" aria-hidden="true" data-astro-cid-4cgfuthx></i> </button> <button class="hitokoto-card__collapse" type="button" aria-label="收起一言" title="收起" data-hitokoto-collapse data-astro-cid-4cgfuthx> <i class="fa-solid fa-chevron-down" aria-hidden="true" data-astro-cid-4cgfuthx></i> </button> </div> </div> <a class="hitokoto-card__text" href="https://hitokoto.cn/" target="_blank" rel="noreferrer" data-hitokoto-text data-astro-cid-4cgfuthx>
获取中...
</a> <p class="hitokoto-card__from" data-hitokoto-from data-astro-cid-4cgfuthx>来自 Hitokoto</p> </aside> <script type="module">(()=>{const o=document.querySelector("[data-hitokoto-card]"),s=o?.querySelector("[data-hitokoto-toggle]"),r=o?.querySelector("[data-hitokoto-text]"),l=o?.querySelector("[data-hitokoto-from]"),k=o?.querySelector("[data-hitokoto-refresh]"),m=o?.querySelector("[data-hitokoto-collapse]");if(!(o instanceof HTMLElement)||!(s instanceof HTMLButtonElement)||!(r instanceof HTMLAnchorElement)||!(l instanceof HTMLElement))return;const g="https://yiyan.biss.click/api?encode=json",u="hitokoto-card-cache",y=360*60*1e3,d={sentence:"生活明朗,万物可爱。",source:"本地缓存",url:"https://hitokoto.cn/"},L=["/","/index.html"].includes(window.location.pathname);function c(t){o.classList.toggle("is-collapsed",!t),s.setAttribute("aria-expanded",String(t)),s.setAttribute("aria-label",t?"收起一言":"展开一言")}function f(){try{const t=localStorage.getItem(u);if(!t)return null;const e=JSON.parse(t);return!e||typeof e.expiresAt!="number"||e.expiresAt<=Date.now()?null:e.data}catch{return null}}function x(t){try{localStorage.setItem(u,JSON.stringify({data:t,expiresAt:Date.now()+y}))}catch{}}function i(t){r.textContent=t.sentence,r.href=t.url||"https://hitokoto.cn/",l.textContent=t.source?`出自 ${t.source}`:"来自 Hitokoto"}async function h({force:t=!1}={}){if(!t){const e=f();if(e){i(e);return}}o.classList.add("is-loading"),r.textContent="获取中...";try{const e=await fetch(g);if(!e.ok)throw new Error(`Hitokoto request failed: ${e.status}`);const n=await e.json(),a=n.hitokoto||n.content||n.sentence||n.text,S=typeof a=="string"&&a.trim()?a.trim():d.sentence,E=typeof n.from=="string"&&n.from.trim()?n.from.trim():"Hitokoto",w=n.uuid?`https://hitokoto.cn/?uuid=${encodeURIComponent(n.uuid)}`:"https://hitokoto.cn/",p={sentence:S,source:E,url:w};x(p),i(p)}catch(e){console.error(e),i(f()||d)}finally{o.classList.remove("is-loading")}}c(L),s.addEventListener("click",()=>{c(o.classList.contains("is-collapsed"))}),k?.addEventListener("click",t=>{t.stopPropagation(),c(!0),h({force:!0})}),m?.addEventListener("click",t=>{t.stopPropagation(),c(!1)}),o.addEventListener("click",t=>{o.classList.contains("is-collapsed")&&(t.target instanceof Element&&t.target.closest("a, button")||c(!0))}),h()})();</script> <div class="custom-context-menu" data-context-menu role="menu" aria-hidden="true"> <div class="context-menu-nav" aria-label="页面导航"> <button type="button" data-context-action="back" aria-label="后退上一页" title="后退上一页"> <i class="fa-solid fa-arrow-left" aria-hidden="true"></i> </button> <button type="button" data-context-action="forward" aria-label="前进下一页" title="前进下一页"> <i class="fa-solid fa-arrow-right" aria-hidden="true"></i> </button> <button type="button" data-context-action="reload" aria-label="刷新页面" title="刷新页面"> <i class="fa-solid fa-rotate-right" aria-hidden="true"></i> </button> <a href="/" aria-label="返回首页" title="返回首页"> <i class="fa-solid fa-house" aria-hidden="true"></i> </a> </div> <div class="context-menu-group" data-selection-group hidden> <button type="button" data-context-action="copy-selection" data-selection-item> <i class="fa-regular fa-copy" aria-hidden="true"></i> <span>复制选中文字</span> </button> <button type="button" data-context-action="search-selection" data-selection-item> <i class="fa-brands fa-microsoft" aria-hidden="true"></i> <span>用 Bing 搜索</span> </button> <button type="button" data-context-action="quote-selection" data-selection-item data-comments-item> <i class="fa-regular fa-comment-dots" aria-hidden="true"></i> <span>引用到评论区</span> </button> </div> <div class="context-menu-group" data-image-group hidden> <button type="button" data-context-action="copy-image"> <i class="fa-regular fa-image" aria-hidden="true"></i> <span>复制图片</span> </button> <button type="button" data-context-action="open-image"> <i class="fa-solid fa-up-right-from-square" aria-hidden="true"></i> <span>新页面打开图片</span> </button> <button type="button" data-context-action="copy-image-url"> <i class="fa-solid fa-link" aria-hidden="true"></i> <span>复制图片地址</span> </button> </div> <div class="context-menu-group"> <a href="/archives/"> <i class="fa-solid fa-box-archive" aria-hidden="true"></i> <span>时间线</span> </a> <a href="/categories/"> <i class="fa-solid fa-folder" aria-hidden="true"></i> <span>分类</span> </a> <a href="/tags/"> <i class="fa-solid fa-hashtag" aria-hidden="true"></i> <span>标签</span> </a> <button type="button" data-context-action="comments" data-comments-item> <i class="fa-regular fa-comment-dots" aria-hidden="true"></i> <span>跳转评论区</span> </button> <button type="button" data-context-action="print"> <i class="fa-solid fa-print" aria-hidden="true"></i> <span>打印页面</span> </button> <a href="/cc/"> <i class="fa-solid fa-circle-info" aria-hidden="true"></i> <span>网站版权</span> </a> </div> </div> <script>
(() => {
const menu = document.querySelector('[data-context-menu]');
if (!menu) return;
const selectionItems = [...menu.querySelectorAll('[data-selection-item]')];
const selectionGroup = menu.querySelector('[data-selection-group]');
const commentsItems = [...menu.querySelectorAll('[data-comments-item]')];
const imageGroup = menu.querySelector('[data-image-group]');
const focusableSelector = 'a[href], button:not([disabled])';
let lastSelectionText = '';
let lastImage = null;
const isNativeContextTarget = (target) =>
target instanceof Element &&
Boolean(target.closest('input, textarea, select, [contenteditable="true"], [contenteditable=""]'));
const getCommentsTarget = () =>
document.querySelector('.twikoo-comments, #twikoo-wrap, #twikoo, .tk-comments-container');
const getSelectionText = () => String(window.getSelection?.() || '').trim();
const getImageTarget = (target) => {
if (!(target instanceof Element)) return null;
const image = target.closest('img');
return image instanceof HTMLImageElement ? image : null;
};
const getImageUrl = () => {
if (!lastImage) return '';
return lastImage.currentSrc || lastImage.src || lastImage.getAttribute('src') || '';
};
const copyText = async (text) => {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'fixed';
textarea.style.inset = '0 auto auto -9999px';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
textarea.remove();
};
const setMenuState = () => {
const hasSelection = lastSelectionText.length > 0;
const hasComments = Boolean(getCommentsTarget());
const hasImage = Boolean(getImageUrl());
selectionItems.forEach((item) => {
item.hidden = !hasSelection;
});
if (selectionGroup) selectionGroup.hidden = !hasSelection;
commentsItems.forEach((item) => {
item.hidden = !hasComments || (item.hasAttribute('data-selection-item') && !hasSelection);
});
if (imageGroup) imageGroup.hidden = !hasImage;
};
const closeMenu = () => {
menu.classList.remove('is-open');
menu.setAttribute('aria-hidden', 'true');
};
const openMenu = (x, y) => {
setMenuState();
menu.classList.add('is-open');
menu.setAttribute('aria-hidden', 'false');
const rect = menu.getBoundingClientRect();
const gap = 10;
const left = Math.min(Math.max(gap, x), window.innerWidth - rect.width - gap);
const top = Math.min(Math.max(gap, y), window.innerHeight - rect.height - gap);
menu.style.left = `${left}px`;
menu.style.top = `${top}px`;
};
const jumpToComments = () => {
const target = getCommentsTarget();
target?.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
const quoteToComments = () => {
jumpToComments();
window.setTimeout(() => {
const textarea = document.querySelector('#twikoo textarea, .twikoo-comments textarea, .tk-input textarea');
if (!(textarea instanceof HTMLTextAreaElement) || !lastSelectionText) return;
const quote = lastSelectionText
.split(/\r?\n/)
.map((line) => `> ${line}`)
.join('\n');
const current = textarea.value.trim();
textarea.value = current ? `${current}\n\n${quote}\n` : `${quote}\n`;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.focus();
}, 500);
};
const searchSelection = () => {
if (!lastSelectionText) return;
const url = `https://www.bing.com/search?q=${encodeURIComponent(lastSelectionText)}`;
window.open(url, '_blank', 'noopener,noreferrer');
};
const copyImage = async () => {
const imageUrl = getImageUrl();
if (!imageUrl) return;
try {
if (!navigator.clipboard?.write || typeof ClipboardItem === 'undefined') {
throw new Error('Image clipboard is not available.');
}
const response = await fetch(imageUrl, { mode: 'cors' });
const blob = await response.blob();
await navigator.clipboard.write([
new ClipboardItem({ [blob.type || 'image/png']: blob }),
]);
} catch {
await copyText(new URL(imageUrl, window.location.href).toString());
}
};
const openImage = () => {
const imageUrl = getImageUrl();
if (!imageUrl) return;
window.open(new URL(imageUrl, window.location.href).toString(), '_blank', 'noopener,noreferrer');
};
document.addEventListener('contextmenu', (event) => {
if (isNativeContextTarget(event.target)) return;
lastSelectionText = getSelectionText();
lastImage = getImageTarget(event.target);
event.preventDefault();
openMenu(event.clientX, event.clientY);
});
document.addEventListener('click', (event) => {
const actionTarget = event.target instanceof Element ? event.target.closest('[data-context-action]') : null;
if (!actionTarget || !menu.contains(actionTarget)) {
closeMenu();
return;
}
const action = actionTarget.dataset.contextAction;
closeMenu();
if (action === 'back') history.back();
if (action === 'forward') history.forward();
if (action === 'reload') location.reload();
if (action === 'copy-selection' && lastSelectionText) copyText(lastSelectionText);
if (action === 'search-selection') searchSelection();
if (action === 'quote-selection') quoteToComments();
if (action === 'copy-image') copyImage();
if (action === 'open-image') openImage();
if (action === 'copy-image-url') copyText(new URL(getImageUrl(), window.location.href).toString());
if (action === 'comments') jumpToComments();
if (action === 'print') window.print();
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') closeMenu();
if (event.key === 'Tab' && menu.classList.contains('is-open')) {
const items = [...menu.querySelectorAll(focusableSelector)].filter((item) => !item.closest('[hidden]'));
if (items.length === 0) return;
const first = items[0];
const last = items[items.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
}
});
window.addEventListener('scroll', closeMenu, { passive: true });
window.addEventListener('resize', closeMenu);
})();
</script> <script src="https://cdn.jsdmirror.com/npm/instantsearch.js@4.56.0"></script> <script src="https://cdn.jsdmirror.com/npm/typesense-instantsearch-adapter@2.7.0/dist/typesense-instantsearch-adapter.min.js"></script> <script src="https://cdn.jsdmirror.com/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script> <script src="/js/random.js"></script> <script src="/js/search/typesense-search.js"></script> <script src="/js/external-links.js"></script> <script>
(() => {
const nav = document.querySelector('.nav');
const toggle = document.querySelector('[data-nav-toggle]');
const menu = document.querySelector('[data-nav-menu]');
if (!nav || !toggle || !menu) return;
function setMenu(open) {
nav.classList.toggle('is-open', open);
toggle.setAttribute('aria-expanded', String(open));
toggle.setAttribute('aria-label', open ? '关闭菜单' : '打开菜单');
}
toggle.addEventListener('click', () => {
setMenu(!nav.classList.contains('is-open'));
});
menu.addEventListener('click', (event) => {
if (event.target instanceof Element && event.target.closest('a')) setMenu(false);
});
window.addEventListener('resize', () => {
if (window.innerWidth > 720) setMenu(false);
});
})();
(() => {
const storageKey = 'site-theme';
const root = document.documentElement;
const button = document.querySelector('[data-theme-toggle]');
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getTheme = () => localStorage.getItem(storageKey) || getSystemTheme();
function applyTheme(theme) {
root.dataset.theme = theme;
button?.setAttribute('aria-label', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
button?.setAttribute('title', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
}
applyTheme(getTheme());
button?.addEventListener('click', () => {
const nextTheme = root.dataset.theme === 'dark' ? 'light' : 'dark';
localStorage.setItem(storageKey, nextTheme);
applyTheme(nextTheme);
});
media.addEventListener('change', () => {
if (!localStorage.getItem(storageKey)) applyTheme(getSystemTheme());
});
})();
(() => {
const runtime = document.getElementById('site-runtime');
if (!runtime) return;
const start = new Date(window.SITE_CONFIG.site.startTime).getTime();
const pad = (value) => String(value).padStart(2, '0');
function updateRuntime() {
const diff = Math.max(0, Date.now() - start);
const days = Math.floor(diff / 86400000);
const hours = Math.floor((diff / 3600000) % 24);
const minutes = Math.floor((diff / 60000) % 60);
const seconds = Math.floor((diff / 1000) % 60);
runtime.textContent = `${days}${pad(hours)}${pad(minutes)}${pad(seconds)} 秒`;
}
updateRuntime();
window.setInterval(updateRuntime, 1000);
})();
</script> </body> </html> <script>
(() => {
const prose = document.querySelector('.prose[data-toc]');
if (!prose) return;
let toc = [];
try {
toc = JSON.parse(prose.dataset.toc || '[]');
} catch {
toc = [];
}
prose.querySelectorAll('h1, h2, h3').forEach((heading, index) => {
const item = toc[index];
if (item?.id && !heading.id) heading.id = item.id;
});
const tocTree = document.querySelector('[data-toc-tree]');
if (tocTree && toc.length > 0) {
const links = [...tocTree.querySelectorAll('[data-toc-link]')];
const groups = [...tocTree.querySelectorAll('[data-toc-group]')];
const headings = toc
.map((item) => document.getElementById(item.id))
.filter(Boolean);
const setActiveToc = (id) => {
links.forEach((link) => {
const isActive = link.getAttribute('href') === `#${id}`;
link.classList.toggle('is-active', isActive);
if (isActive) link.setAttribute('aria-current', 'location');
else link.removeAttribute('aria-current');
});
const activeLink = tocTree.querySelector(`[data-toc-link][href="#${CSS.escape(id)}"]`);
const activeGroup = activeLink?.closest('[data-toc-group]');
groups.forEach((group) => group.classList.toggle('is-open', group === activeGroup));
};
const updateToc = () => {
const anchorOffset = 132;
let activeId = headings[0]?.id;
headings.forEach((heading) => {
if (heading.getBoundingClientRect().top <= anchorOffset) activeId = heading.id;
});
if (activeId) setActiveToc(activeId);
};
tocTree.addEventListener('click', (event) => {
const link = event.target.closest?.('[data-toc-link]');
if (!link) return;
const group = link.closest('[data-toc-group]');
groups.forEach((item) => item.classList.toggle('is-open', item === group));
});
updateToc();
window.addEventListener('scroll', updateToc, { passive: true });
window.addEventListener('resize', updateToc);
}
const summaryText = document.querySelector('.article-summary-text');
if (!summaryText) return;
const fullText = summaryText.dataset.summaryText || summaryText.textContent || '';
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduceMotion) {
summaryText.textContent = fullText;
return;
}
summaryText.textContent = '';
let index = 0;
function typeSummary() {
index += 1;
summaryText.textContent = fullText.slice(0, index);
if (index < fullText.length) {
window.setTimeout(typeSummary, 34);
}
}
window.setTimeout(typeSummary, 280);
})();
</script> <script>
(() => {
const prose = document.querySelector('.post-article .prose');
if (!prose) return;
const collapsedLineCount = 8;
const copyLabels = {
idle: '复制',
done: '已复制',
error: '复制失败',
};
const languageNames = {
bash: 'Bash',
c: 'C',
cpp: 'C++',
cs: 'C#',
css: 'CSS',
html: 'HTML',
js: 'JavaScript',
json: 'JSON',
jsx: 'JSX',
md: 'Markdown',
powershell: 'PowerShell',
py: 'Python',
shell: 'Shell',
sh: 'Shell',
ts: 'TypeScript',
tsx: 'TSX',
txt: 'Text',
yaml: 'YAML',
yml: 'YAML',
};
function getCodeLanguage(pre, code) {
const rawLanguage =
pre.dataset.language ||
code.dataset.language ||
[...pre.classList, ...code.classList]
.find((className) => className.startsWith('language-'))
?.replace(/^language-/, '') ||
'';
const normalized = rawLanguage.trim().toLowerCase();
return languageNames[normalized] || normalized.toUpperCase() || 'Code';
}
function getCodeText(code, lines) {
if (lines.length > 0) return lines.map((line) => line.textContent || '').join('\n');
return code.textContent || '';
}
prose.querySelectorAll('img').forEach((image) => {
if (image.closest('a, .article-header-cover')) return;
const src = image.currentSrc || image.getAttribute('src');
if (!src) return;
const link = document.createElement('a');
link.className = 'fancybox';
link.href = src;
link.dataset.fancybox = 'article-gallery';
link.dataset.caption = image.getAttribute('alt') || '';
image.parentNode?.insertBefore(link, image);
link.appendChild(image);
});
prose.querySelectorAll('table').forEach((table) => {
if (table.closest('.table-scroll')) return;
const wrapper = document.createElement('div');
wrapper.className = 'table-scroll';
table.parentNode?.insertBefore(wrapper, table);
wrapper.appendChild(table);
});
prose.querySelectorAll('.butterfly-hide-inline').forEach((item) => {
const button = item.querySelector('.butterfly-hide-toggle');
if (!button) return;
button.addEventListener('click', () => {
item.classList.toggle('is-open');
});
});
if (window.Fancybox) {
window.Fancybox.bind('[data-fancybox="article-gallery"]', {
compact: false,
dragToClose: true,
Images: {
zoom: true,
},
});
}
async function copyText(text) {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'fixed';
textarea.style.top = '-9999px';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
textarea.remove();
}
prose.querySelectorAll('pre').forEach((pre) => {
if (pre.closest('.code-block')) return;
const code = pre.querySelector('code');
if (!code) return;
const wrapper = document.createElement('div');
wrapper.className = 'code-block';
pre.parentNode?.insertBefore(wrapper, pre);
wrapper.appendChild(pre);
const header = document.createElement('div');
header.className = 'code-block-header';
const language = document.createElement('span');
language.className = 'code-block-language';
language.textContent = getCodeLanguage(pre, code);
const toolbar = document.createElement('div');
toolbar.className = 'code-block-toolbar';
const copyButton = document.createElement('button');
copyButton.className = 'code-block-copy';
copyButton.type = 'button';
copyButton.textContent = copyLabels.idle;
copyButton.setAttribute('aria-label', '复制代码');
const toggleButton = document.createElement('button');
toggleButton.className = 'code-block-toggle';
toggleButton.type = 'button';
toggleButton.textContent = '展开';
toggleButton.setAttribute('aria-expanded', 'false');
toolbar.append(copyButton, toggleButton);
header.append(language, toolbar);
wrapper.appendChild(header);
const codeLines = [...code.querySelectorAll(':scope > .line')];
if (codeLines.length > 0) {
wrapper.classList.add('has-line-numbers');
wrapper.style.setProperty('--line-number-width', `${String(codeLines.length).length + 1}ch`);
codeLines.forEach((line, index) => {
line.dataset.line = String(index + 1);
});
}
const lineCount = codeLines.length || (code.textContent || '').split(/\r?\n/).length;
if (lineCount > collapsedLineCount) wrapper.classList.add('is-collapsible');
copyButton.addEventListener('click', async () => {
try {
await copyText(getCodeText(code, codeLines));
copyButton.textContent = copyLabels.done;
window.setTimeout(() => {
copyButton.textContent = copyLabels.idle;
}, 1400);
} catch {
copyButton.textContent = copyLabels.error;
window.setTimeout(() => {
copyButton.textContent = copyLabels.idle;
}, 1600);
}
});
toggleButton.addEventListener('click', () => {
const isExpanded = wrapper.classList.toggle('is-expanded');
toggleButton.textContent = isExpanded ? '收起' : '展开';
toggleButton.setAttribute('aria-expanded', String(isExpanded));
});
});
})();
</script>