Skip to content

Commit 5c798e0

Browse files
committed
Upgrade Nuget
1 parent 673284f commit 5c798e0

1 file changed

Lines changed: 122 additions & 5 deletions

File tree

.github/copilot-instructions.md

Lines changed: 122 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
| **一致** | 风格、结构、命名、API 行为稳定 |
1313
| **可控** | 限制改动影响面,可审计,兼容友好 |
1414
| **可靠** | 先检索再生成,不虚构,不破坏现有合约 |
15+
| **主动** | 发现问题主动修复,不回避合理优化 |
1516

1617
---
1718

@@ -31,12 +32,40 @@
3132

3233
1. **需求分类**:功能/修复/性能/重构/文档
3334
2. **检索**:相关类型、目录、方法、已有扩展/工具(**优先复用**
34-
3. **评估**:是否公共 API?是否性能热点?
35+
3. **评估**:是否公共 API?是否性能热点?**是否存在潜在问题?**
3536
4. **设计**:列出改动点 + 兼容/降级策略
36-
5. **实施**:局部编辑,限制影响面;保留原注释与结构
37-
6. **验证**:编译通过;运行相关单元测试(未找到需说明)
37+
5. **实施**
38+
- 完成用户请求的核心任务
39+
- **顺带修复**发现的明显缺陷(资源泄漏、空引用、逻辑错误)
40+
- **顺带优化**可简化的重复代码
41+
- 保留原注释与结构,除非注释本身有误
42+
6. **验证**
43+
- 代码变更:必须编译通过;运行相关单元测试(未找到需说明)
44+
- 仅文档变更(未修改任何代码文件):可跳过编译与单元测试
3845
7. **说明**:变更摘要/影响范围/风险点
3946

47+
### 3.1 主动优化原则
48+
49+
当用户请求分析或优化代码时,**应主动**
50+
51+
| 类型 | 行动 |
52+
|------|------|
53+
| **缺陷修复** | 资源泄漏、空引用风险、并发问题、逻辑错误 → 直接修复 |
54+
| **性能优化** | 无用分配、重复计算、可池化资源 → 评估后优化 |
55+
| **代码简化** | 重复代码提取、冗余判断合并、现代语法替换 → 在不影响可读性前提下简化 |
56+
| **注释完善** | 缺失的参数注释、过时的描述 → 补充或修正 |
57+
58+
**不应过度保守**
59+
- ❌ 仅添加注释而忽略明显的代码问题
60+
- ❌ 发现资源泄漏却不修复
61+
- ❌ 看到重复代码却不提取
62+
- ❌ 用户要求优化时只做表面工作
63+
64+
**保持谨慎的场景**
65+
- 公共 API 签名变更 → 需说明兼容性影响
66+
- 性能关键路径 → 需有依据或说明推理
67+
- 大范围重构 → 需先与用户确认范围
68+
4069
---
4170

4271
## 4. 编码规范
@@ -48,6 +77,7 @@
4877
| 语言版本 | `<LangVersion>latest</LangVersion>`,所有目标框架均使用最新 C# 语法 |
4978
| 命名空间 | file-scoped namespace |
5079
| 类型名 | **必须**使用 .NET 正式名 `String`/`Int32`/`Boolean` 等,避免 `string`/`int`/`bool` |
80+
| 兼容性 | 代码需兼容 .NET 4.5+;**禁止**使用 `ArgumentNullException.ThrowIfNull`,改用 `if (value == null) throw new ArgumentNullException(nameof(value));` |
5181
| 单文件 | 每文件一个主要公共类型;较大平台差异使用 `partial` |
5282

5383
### 4.2 命名规范
@@ -150,7 +180,6 @@ var result = code switch
150180

151181
// 目标类型 new
152182
using var ms = new MemoryStream();
153-
List<String> list = []; // C# 12,仅 net8.0+ 运行时可用
154183

155184
// record(DTO 场景)
156185
public record UserInfo(String Name, Int32 Age);
@@ -159,6 +188,81 @@ public record UserInfo(String Name, Int32 Age);
159188
if (obj is String { Length: > 0 } str) { }
160189
```
161190

191+
### 4.6 集合表达式
192+
193+
优先使用集合表达式 `[]` 初始化集合,代码更简洁:
194+
195+
```csharp
196+
// ✅ 属性定义:使用集合表达式
197+
public List<String> Tags { get; set; } = [];
198+
public Dictionary<String, Object> Data { get; set; } = [];
199+
public Int32[] Numbers { get; set; } = [];
200+
201+
// ❌ 避免冗长的初始化方式
202+
public List<String> Tags { get; set; } = new List<String>();
203+
public List<String> Tags { get; set; } = new();
204+
205+
// ✅ 方法内局部变量
206+
List<String> list = [];
207+
var items = new List<Item>(); // 需要立即 Add 时可用 new
208+
209+
// ✅ 带初始值的集合
210+
List<Int32> nums = [1, 2, 3];
211+
String[] names = ["Alice", "Bob"];
212+
Dictionary<String, Int32> scores = new() { ["Math"] = 90, ["English"] = 85 };
213+
214+
// ✅ 集合展开(spread)
215+
List<Int32> combined = [..first, ..second, 100];
216+
217+
// ✅ 返回空集合
218+
public IList<String> GetItems() => [];
219+
```
220+
221+
### 4.7 Null 条件运算符
222+
223+
优先使用 `?.`(null 条件运算符)简化空值检查,提升代码简洁性与可读性:
224+
225+
```csharp
226+
// ✅ 方法调用:使用 null 条件运算符
227+
span?.AppendTag("test");
228+
handler?.Invoke(this, args);
229+
list?.Clear();
230+
231+
// ❌ 避免冗余的 if 判断
232+
if (span != null) span.AppendTag("test");
233+
if (handler != null) handler.Invoke(this, args);
234+
235+
// ✅ 属性赋值:使用 null 条件赋值(C# 14 新特性)
236+
customer?.Order = GetCurrentOrder();
237+
span?.Value = 1234;
238+
config?.Name = "test";
239+
240+
// ❌ 避免冗余的 if 判断
241+
if (customer != null) customer.Order = GetCurrentOrder();
242+
if (span != null) span.Value = 1234;
243+
244+
// ✅ 复合赋值运算符也支持
245+
counter?.Count += 1;
246+
list?.Capacity *= 2;
247+
248+
// ✅ 链式调用:安全访问嵌套属性
249+
var name = user?.Profile?.Name;
250+
var count = order?.Items?.Count ?? 0;
251+
252+
// ✅ 结合 null 合并运算符提供默认值
253+
var length = str?.Length ?? 0;
254+
var display = item?.ToString() ?? "N/A";
255+
256+
// ✅ 索引器访问
257+
var first = list?[0];
258+
var value = dict?["key"];
259+
260+
// ✅ 委托调用(推荐写法)
261+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
262+
```
263+
264+
**注意**:null 条件赋值时,右侧表达式仅在左侧非 null 时才会求值;不支持自增/自减运算符(`++`/`--`)。
265+
162266
---
163267

164268
## 5. 多目标框架
@@ -371,20 +475,32 @@ catch (Exception ex)
371475
- 输出前检索现有实现,**禁止重复造轮子**
372476
- 先列方案再实现
373477
- 标记不确定上下文为"需查看文件"
478+
- **发现明显缺陷时主动修复**(资源泄漏、空引用、逻辑错误)
479+
- **用户要求优化时深入分析**,不做表面工作
480+
481+
### 鼓励
482+
483+
- 提取重复代码为公共方法
484+
- 简化冗余的条件判断
485+
- 使用现代 C# 语法改进可读性
486+
- 补充缺失的资源释放逻辑
487+
- 修正错误或过时的注释
374488

375489
### 禁止
376490

377491
- 虚构 API/文件/类型
378492
- 伪造测试结果/性能数据
379493
- 擅自删除公共/受保护成员
380-
- 擅自删除已有代码注释
494+
- 擅自删除已有代码注释(除非注释本身错误)
381495
- 仅删除空白行制造"格式优化"提交
382496
- 删除循环体的花括号
383497
-`<summary>` 拆成多行
384498
-`String`/`Int32` 改为 `string`/`int`
385499
- 新增外部依赖(除非说明理由并给出权衡)
386500
- 在热点路径添加未缓存反射/复杂 Linq
387501
- 输出敏感凭据/内部地址
502+
- **发现问题却视而不见**
503+
- **用户要求优化时仅做注释/测试等表面工作**
388504

389505
---
390506

@@ -418,6 +534,7 @@ catch (Exception ex)
418534
|------|------|
419535
| **热点路径** | 经性能分析或高频调用栈确认的关键执行段 |
420536
| **基线** | 变更前的功能/性能参考数据 |
537+
| **顺带修复** | 在完成主任务过程中,修复发现的相关问题 |
421538

422539
---
423540

0 commit comments

Comments
 (0)