Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .github/actions/report-dotnet-runtime/action.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
name: Report selected .NET runtimes
description: Execute a small probe for every target framework declared by Common.props
inputs:
expected-culture:
description: Optional culture to require for both CurrentCulture and CurrentUICulture
required: false
default: ''
runs:
using: composite
steps:
- name: Execute runtime probes
shell: pwsh
env:
EXPECTED_CULTURE: ${{ inputs.expected-culture }}
run: |
$ErrorActionPreference = 'Stop'
$probeDirectory = Join-Path $env:RUNNER_TEMP ("dotnet-runtime-probe-" + [Guid]::NewGuid().ToString('N'))
Expand All @@ -16,6 +23,14 @@ runs:
Set-Content (Join-Path $probeDirectory 'RuntimeProbe.csproj') $project -Encoding utf8
$source = @'
System.Console.WriteLine($"Actual runtime: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}; version={System.Environment.Version}; architecture={System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture}");
string culture = System.Globalization.CultureInfo.CurrentCulture.Name;
string uiCulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
System.Console.WriteLine($"Actual culture: {culture}; UI culture: {uiCulture}");
if (args.Length > 0 && !string.IsNullOrEmpty(args[0])
&& (culture != args[0] || uiCulture != args[0]))
{
throw new System.InvalidOperationException($"Expected culture {args[0]}, got {culture}/{uiCulture}.");
}
'@
Set-Content (Join-Path $probeDirectory 'Program.cs') $source -Encoding utf8
Push-Location $probeDirectory
Expand All @@ -26,7 +41,7 @@ runs:
$frameworks = ([xml](Get-Content $commonPath -Raw)).Project.PropertyGroup.TargetFrameworks.Split(';')
foreach ($framework in $frameworks) {
Write-Host "Target framework: $framework"
dotnet (Join-Path $probeDirectory "bin/Debug/$framework/RuntimeProbe.dll")
dotnet (Join-Path $probeDirectory "bin/Debug/$framework/RuntimeProbe.dll") $env:EXPECTED_CULTURE
if ($LASTEXITCODE -ne 0) { throw "Runtime probe failed for ${framework}: $LASTEXITCODE" }
}
} finally {
Expand Down
37 changes: 21 additions & 16 deletions .github/workflows/LocalesTest.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test Different Locales
name: Chinese and Cross-Locale Validation

on:
push:
Expand All @@ -8,12 +8,18 @@ on:

jobs:
set-build-and-test-locale-languages:
name: Build and Test ${{ matrix.locale-lang }} Locale On Ubuntu
name: ${{ matrix.label }} on Ubuntu
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
locale-lang: ["pt_BR.UTF-8", "fr_FR.UTF-8"]
include:
- locale: zh_CN.UTF-8
culture: zh-CN
label: 简体中文主验证
- locale: fr_FR.UTF-8
culture: fr-FR
label: 法语跨区域检查
steps:
- uses: actions/checkout@v4
- name: Verify repository text encoding
Expand All @@ -26,6 +32,15 @@ jobs:
dotnet-version: |
6.0.x
7.0.x
- name: Configure test locale
shell: bash
env:
TEST_LOCALE: ${{ matrix.locale }}
run: |
sudo locale-gen "$TEST_LOCALE"
sudo localectl set-locale LANG="$TEST_LOCALE"
sudo update-locale LANG="$TEST_LOCALE"
printf 'LANG=%s\nLC_ALL=%s\n' "$TEST_LOCALE" "$TEST_LOCALE" >> "$GITHUB_ENV"
- name: Get Build Information
run: |
dotnet --info
Expand All @@ -34,6 +49,8 @@ jobs:
dotnet --list-runtimes
- name: Verify actual target runtimes
uses: ./.github/actions/report-dotnet-runtime
with:
expected-culture: ${{ matrix.culture }}
- name: Set up dependency caching for faster builds
uses: actions/cache@v4
id: nuget-cache
Expand All @@ -45,22 +62,10 @@ jobs:
restore-keys: |
${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
${{ runner.os }}-nuget-
- name: SetLocale To ${{ matrix.locale-lang }}, and Build and Test
- name: Build and test all frameworks in the selected locale
run: |
sudo locale-gen ${{ matrix.locale-lang }}
sudo localectl set-locale LANG=${{ matrix.locale-lang }}
LANG=${{ matrix.locale-lang }}
export LANG=${{ matrix.locale-lang }}
sudo update-locale LANG=${{ matrix.locale-lang }}
echo Current Locale Settings:
echo Run locale to get the information about the current locale and language settings:
locale
echo Run locale -a to list all enabled locales:
locale -a
echo Run localectl status to find system locale status.
localectl status
echo Visual Test
echo "Printing date"
date
echo Restore dependencies
dotnet restore
Expand Down
108 changes: 56 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,95 @@
# EssentialCSharp - C#本质论
# EssentialCSharp — C# 本质论

本项目包含《C# 12.0本质论》的源代码,2024年清华大学出版社出版。
[![构建与测试](https://github.com/transbot/EssentialCSharp/actions/workflows/build-and-test.yml/badge.svg?branch=v12.0Chinese&event=push)](https://github.com/transbot/EssentialCSharp/actions/workflows/build-and-test.yml?query=branch%3Av12.0Chinese)

## 中文版主页请访问[周靖的博客](https://bookzhou.com)
## 英文版在线手稿请访问[EssentialCSharp.com](https://essentialcsharp.com)
## 在英文版(print edition)中发现并纠正了不少疏漏,已提供英文版勘误。
![C# 12 0本质论(第8版)-平展封](https://github.com/user-attachments/assets/bb84e67a-e659-4ab3-ba76-438ca110458a)
本仓库提供《C# 12.0 本质论》(第 8 版,清华大学出版社,2024 年)中文版的配套源代码。

代码及测试以中文版译稿和本仓库已修正的示例为准。中文版翻译过程中核对并修订了英文纸质版的部分疏漏,相关勘误和配套资源见[中文版主页](https://bookzhou.com)。

[EssentialCSharp.com](https://essentialcsharp.com) 提供英文在线资料,参阅时请留意版次和代码清单编号的差异。

![《C# 12.0 本质论》第 8 版封面](https://github.com/user-attachments/assets/bb84e67a-e659-4ab3-ba76-438ca110458a)

## 中文版购买链接

- [京东官方](https://item.jd.com/14279697.html)
- [当当网](https://product.dangdang.com/29781408.html)
- [京东](https://item.jd.com/14279697.html)
- [当当](https://product.dangdang.com/29781408.html)

## 中英文版配套资源(含试读PDF)备用下载地址
## 配套资源与试读

- [百度网盘](https://pan.baidu.com/s/1yd43W)
- 也可以访问[中文版主页](https://bookzhou.com)从本地下载(已完成)
中英文版配套资源和试读 PDF 可从[中文版主页](https://bookzhou.com)获取,也可使用[百度网盘备用地址](https://pan.baidu.com/s/1yd43W)。

## 要求
## 开发环境

- [.NET](https://dotnet.microsoft.com/zh-cn/download) - 该项目当前经过.NET 8.0、7.0和6.0的测试。
- [Visual Studio](https://visualstudio.microsoft.com/downloads/) - 已集成.NET Core,这是我们主推的IDE,用它可以方便地入门。
- [Git](https://git-scm.com/book/zh/v2) - 虽然不是必需的,但它是一个可以快速下载此代码仓库的好工具。如果不喜欢使用命令行,建议使用Visual Studio自带的Git功能,或者使用第三方工具,例如[GitKraken](https://www.gitkraken.com/invite/bX2Nqsqr) 。
- [.NET SDK](https://dotnet.microsoft.com/zh-cn/download):使用 .NET 8 SDK 构建项目,SDK 选择规则见 `global.json`。项目保留 `net8.0`、`net7.0` 和 `net6.0` 三个目标框架;运行或测试某个目标框架时,需要安装对应的运行时。
- [Visual Studio](https://visualstudio.microsoft.com/downloads/):可使用支持 .NET 8 的 Visual Studio 2022 进行开发,也可使用下文的 .NET CLI 命令。
- [Git](https://git-scm.com/book/zh/v2):可用于克隆仓库和获取更新;也可使用 Visual Studio 的 Git 功能。

## 运行代码

### Visual Studio

1. **EssentialCSharp.sln** 是项目的主解决方案,请使用Visual Studio打开。
2. 打开解决方案文件后,选择生成->生成解决方案,使用Visual Studio编译代码。
- 注意:在执行源代码之前,需要将和当前章对应的项目设为启动项目。例如,要执行第1章的示例,那么应该右键单击Chapter01项目,然后选择“设为启动项目”。如果选择一个目标章作为启动项目,但输入其他章的代码清单编号,那么会导致异常,并显示消息:“不存在和代码清单...对应的章”,“不存在代码清单...”或者“异常”。
3. 要运行代码,请按F5或选择调试->开始调试。
4. 运行后,程序将提示输入要执行的代码清单编号(例如,18.33)。
- 注意:如前所述,只能输入本书合法的代码清单编号。

![image](https://github.com/transbot/EssentialCSharp/assets/12107254/9b8891de-3df3-48d9-838e-1a36750e7102)
1. 打开主解决方案 `EssentialCSharp.sln`。
2. 选择“生成 → 生成解决方案”。
3. 将要阅读的章节设为启动项目。例如,运行第 1 章时,右键单击 `Chapter01`,选择“设为启动项目”。
4. 选择 .NET 8 目标框架,按 F5 或选择“调试 → 开始调试”。
5. 按程序提示输入当前章节的代码清单编号,例如 `1.1`。运行其他章节时,请切换到对应的启动项目。

![运行代码清单示例](https://github.com/transbot/EssentialCSharp/assets/12107254/9b8891de-3df3-48d9-838e-1a36750e7102)

### .NET CLI

### Dotnet CLI
在仓库根目录(包含 `EssentialCSharp.sln` 的目录)还原并构建项目:

1. 从本地终端导航到EssentialCSharp的根目录(根目录是包含`EssentialCSharp.sln`文件的目录)。
2. 从该根目录运行以下命令以还原和构建所有项目:
```bash
dotnet restore
dotnet build --no-restore
```

```C#
dotnet restore
dotnet build
```
例如,从仓库根目录运行第 1 章:

3. 要运行代码,请首先导航到希望执行的那个章节所在的项目目录。例如,要执行第1章的示例,需要先导航到Chapter01目录(例如:`cd src/Chapter01`)。
4. 然后使用`dotnet run`命令启动程序,并按照提示输入要执行的代码清单编号。
- 注意:只能输入在当前运行的项目(本例是Chapter01)中存在的代码清单编号。
5. 还可以使用`dotnet run -p <projectfile>`命令,其中project file是要执行的项目文件的路径(例如,`dotnet run -p .\src\Chapter01\Chapter01.csproj`)。执行时,程序将提示要执行哪个代码清单。
```bash
dotnet run --project src/Chapter01/Chapter01.csproj --framework net8.0
```

.NET CLI工具的文档可以在这里找到:https://learn.microsoft.com/zh-cn/dotnet/core/tools/
项目包含多个目标框架,运行时需使用 `--framework` 指定其中一个。程序启动后,按提示输入当前章节的代码清单编号。也可以先进入章节目录,再执行 `dotnet run --framework net8.0`。

更多命令说明见 [.NET CLI 文档](https://learn.microsoft.com/zh-cn/dotnet/core/tools/)。

## 测试

测试断言按中文版译稿及本仓库的配套示例维护,覆盖现有的 net6.0、net7.0 和 net8.0 目标框架。
测试断言按中文版译稿及本仓库的配套示例维护,覆盖 `net6.0`、`net7.0` 和 `net8.0` 三个目标框架。

部分清单刻意演示编译错误或运行时异常;对应测试会核对编译诊断或预期异常,不应为了通过测试而消除这些教学示例中的错误。
CI 在 Windows、Linux 和 macOS 上执行构建与测试,并在 Linux 上分别执行“简体中文主验证”(zh-CN)和“法语跨区域检查”(fr-FR)。两组区域测试均运行全部现有测试及三个目标框架:简体中文组覆盖中文读者的典型环境,法语组验证数字、日期等区域格式差异。CI 会核对实际区域设置和目标运行时。

许多代码清单都有相应的单元测试。
部分清单刻意演示编译错误或运行时异常;对应测试会核对编译诊断或预期异常。请保留这些教学示例的设计意图。

在Visual Studio中,要执行测试,请打开测试项目
在 Visual Studio 中,可以通过“测试资源管理器”运行全部测试,也可以右键单击具体测试方法,选择“运行测试”或“调试测试”。详见 [Visual Studio 测试文档](https://learn.microsoft.com/visualstudio/test/run-unit-tests-with-test-explorer)。

并导航到与您要执行的代码清单对应的测试。然后,在测试方法上右键单击,选择运行测试(Ctrl+R,T)或调试测试(Ctrl+R,Ctrl+T)。或者,打开Test Explorer窗口,并从那里运行一些或所有测试([更多信息](https://learn.microsoft.com/visualstudio/test/run-unit-tests-with-test-explorer))。
从仓库根目录运行全部测试:

在dotnet test中,要在所有项目中运行所有测试,请在根EssentialCSharp目录中的命令提示符上运行`dotnet test`。要运行单个项目的测试,请在要执行的测试的测试项目的测试目录中使用dotnet test命令。
```bash
dotnet test
```

## 阅读源代码

在源代码中,有一些可能与在书中查看源代码时看起来不同的地方。这是因为即使书中的示例直接来自这个存储库,但并非所有代码都在书中原样显示。
运行单章测试时,可指定测试项目,例如:

一些注意事项:
```bash
dotnet test src/Chapter01.Tests/Chapter01.Tests.csproj
```

当代码中有匹配的`#region INCLUDE`和`#endregion INCLUDE`标签时,在这两个标签之间的是在本书中能够看到的源代码。
## 阅读源代码

当代码中有匹配的`#region EXCLUDE`和`#endregion EXCLUDE`标签时,即使这些标签在两个`INCLUDE`标签之间,此部分也会在书中省略,并用`// ...`替换,目的是让您将重点放在当前讲解的主题上。
配套工程包含运行入口、测试和辅助代码,因此部分文件与书中的展示形式有所不同。阅读代码时,可通过以下标记识别书中展示的部分:

此外,任何以`// EXCLUDE`结尾的行都在书中省略了。
- `#region INCLUDE` 与 `#endregion INCLUDE` 之间是书中展示的代码。
- `#region EXCLUDE` 与 `#endregion EXCLUDE` 之间的内容在书中省略,通常以 `// ...` 表示。
- 行尾带有 `// EXCLUDE` 的代码在书中省略。

## 问题/错误
## 问题反馈与修正

如果有任何问题或发现任何错误,请随时打开[本书中文版Git](https://github.com/transbot/EssentialCSharp/discussions)、[Pull Request](https://github.com/transbot/EssentialCSharp/pulls)或[Issue](https://github.com/transbot/EssentialCSharp/discussions)。
使用 [Issues](https://github.com/transbot/EssentialCSharp/issues) 报告问题或错误,通过 [Discussions](https://github.com/transbot/EssentialCSharp/discussions) 讨论用法,通过 [Pull requests](https://github.com/transbot/EssentialCSharp/pulls) 提交修正。反馈时请注明中文版版次、章节或代码清单编号,以及复现步骤。

另外,请访问[本书中文版主页](https://bookzhou.com),获取最新资讯、下载和勘误。
资讯、下载与勘误请访问[中文版主页](https://bookzhou.com)。

## 祝您编码愉快
祝编程愉快!
Loading