Skip to content

Commit fa5f520

Browse files
committed
由 AI 生成属性默认值的部分
1 parent 994e345 commit fa5f520

File tree

3 files changed

+165
-3
lines changed

3 files changed

+165
-3
lines changed

docs/en/README.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,60 @@ class Options
193193

194194
If a required option is not provided, a `RequiredPropertyNotAssignedException` will be thrown during parsing.
195195

196+
## Property Initial Values and Accessors
197+
198+
When defining option types, it's important to understand the relationship between property initial values and accessor modifiers (`init`, `required`):
199+
200+
```csharp
201+
class Options
202+
{
203+
// Incorrect example: when using init or required, default values will be ignored
204+
[Option('f', "format")]
205+
public string Format { get; init; } = "json"; // Default value won't work!
206+
207+
// Correct example: use set to retain the default value
208+
[Option('f', "format")]
209+
public string Format { get; set; } = "json"; // Default value will be preserved
210+
}
211+
```
212+
213+
### Important Notes About Property Initial Values
214+
215+
1. **Behavior with `init` or `required`**:
216+
- When a property includes `required` or `init` modifiers, the initial value will be ignored
217+
- If the option is not provided in command line arguments, the property will be set to `default(T)` (null for reference types)
218+
- This is determined by C# language design, not a limitation of the command line library
219+
220+
2. **How to preserve default values**:
221+
- If you need to provide a default value for a property, use `{ get; set; }` instead of `{ get; init; }`
222+
223+
3. **Nullable types and warning handling**:
224+
- For non-required reference type properties, mark them as nullable (e.g., `string?`) to avoid nullable warnings
225+
- For value types (e.g., `int`, `bool`), if you want to keep the default value rather than null, don't mark them as nullable
226+
227+
Example:
228+
229+
```csharp
230+
class OptionsBestPractice
231+
{
232+
// Required option: using required, no need to worry about default values
233+
[Option("input")]
234+
public required string InputFile { get; init; }
235+
236+
// Optional option: mark as nullable type to avoid warnings
237+
[Option("output")]
238+
public string? OutputFile { get; init; }
239+
240+
// Option needing default value: use set instead of init
241+
[Option("format")]
242+
public string Format { get; set; } = "json";
243+
244+
// Value type option: no need to mark as nullable
245+
[Option("count")]
246+
public int Count { get; set; } = 1;
247+
}
248+
```
249+
196250
## Command Handling and Verbs
197251

198252
You can use the command handler pattern to handle different commands (verbs), similar to `git commit`, `git push`, etc. DotNetCampus.CommandLine provides several ways to add command handlers:
@@ -241,7 +295,7 @@ internal class ConvertCommandHandler : ICommandHandler
241295
public string? OutputFile { get; init; }
242296

243297
[Option('f', "format")]
244-
public string Format { get; init; } = "json";
298+
public string Format { get; set; } = "json";
245299

246300
public Task<int> RunAsync()
247301
{

docs/zh-hans/README.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,60 @@ class Options
193193

194194
如果未提供必需选项,解析时会抛出`RequiredPropertyNotAssignedException`异常。
195195

196+
## 属性初始值与访问器修饰符
197+
198+
在定义选项类型时,需要注意属性初始值与访问器修饰符(`init``required`)之间的关系:
199+
200+
```csharp
201+
class Options
202+
{
203+
// 错误示例:当使用 init 或 required 时,默认值将被忽略
204+
[Option('f', "format")]
205+
public string Format { get; init; } = "json"; // 默认值不会生效!
206+
207+
// 正确示例:使用 set 以保留默认值
208+
[Option('f', "format")]
209+
public string Format { get; set; } = "json"; // 默认值会正确保留
210+
}
211+
```
212+
213+
### 关于属性初始值的重要说明
214+
215+
1. **使用 `init``required` 时的行为**
216+
- 当属性包含 `required``init` 修饰符时,属性的初始值会被忽略
217+
- 如果命令行参数中未提供该选项的值,属性将被设置为 `default(T)`(对于引用类型为 `null`
218+
- 这是由 C# 语言特性决定的,命令行库如果希望突破此限制需要针对所有属性排列组合进行处理,显然是非常浪费的
219+
220+
2. **保留默认值的方式**
221+
- 如果需要为属性提供默认值,应使用 `{ get; set; }` 而非 `{ get; init; }`
222+
223+
3. **可空类型与警告处理**
224+
- 对于非必需的引用类型属性,应将其标记为可空(如 `string?`)以避免可空警告
225+
- 对于值类型(如 `int``bool`),如果想保留默认值而非 `null`,不应将其标记为可空
226+
227+
示例:
228+
229+
```csharp
230+
class OptionsBestPractice
231+
{
232+
// 必需选项:使用 required,无需担心默认值
233+
[Option("input")]
234+
public required string InputFile { get; init; }
235+
236+
// 可选选项:标记为可空类型以避免警告
237+
[Option("output")]
238+
public string? OutputFile { get; init; }
239+
240+
// 需要默认值的选项:使用 set 而非 init
241+
[Option("format")]
242+
public string Format { get; set; } = "json";
243+
244+
// 值类型选项:不需要标记为可空
245+
[Option("count")]
246+
public int Count { get; set; } = 1;
247+
}
248+
```
249+
196250
## 命令处理与谓词
197251

198252
你可以使用命令处理器模式处理不同的命令(谓词),类似于`git commit``git push`等。DotNetCampus.CommandLine 提供了多种添加命令处理器的方式:
@@ -241,7 +295,7 @@ internal class ConvertCommandHandler : ICommandHandler
241295
public string? OutputFile { get; init; }
242296

243297
[Option('f', "format")]
244-
public string Format { get; init; } = "json";
298+
public string Format { get; set; } = "json";
245299

246300
public Task<int> RunAsync()
247301
{

docs/zh-hant/README.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,60 @@ class Options
193193

194194
如果未提供必需選項,解析時會拋出`RequiredPropertyNotAssignedException`異常。
195195

196+
## 屬性初始值與訪問器修飾符
197+
198+
在定義選項類型時,需要注意屬性初始值與訪問器修飾符(`init``required`)之間的關係:
199+
200+
```csharp
201+
class Options
202+
{
203+
// 錯誤示例:當使用 init 或 required 時,默認值將被忽略
204+
[Option('f', "format")]
205+
public string Format { get; init; } = "json"; // 默認值不會生效!
206+
207+
// 正確示例:使用 set 以保留默認值
208+
[Option('f', "format")]
209+
public string Format { get; set; } = "json"; // 默認值會正確保留
210+
}
211+
```
212+
213+
### 關於屬性初始值的重要說明
214+
215+
1. **使用 `init``required` 時的行為**
216+
- 當屬性包含 `required``init` 修飾符時,屬性的初始值會被忽略
217+
- 如果命令行參數中未提供該選項的值,屬性將被設置為 `default(T)`(對於引用類型為 `null`
218+
- 這是由 C# 語言特性決定的,命令行庫如果希望突破此限制需要針對所有屬性排列組合進行處理,顯然是非常浪費的
219+
220+
2. **保留默認值的方式**
221+
- 如果需要為屬性提供默認值,應使用 `{ get; set; }` 而非 `{ get; init; }`
222+
223+
3. **可空類型與警告處理**
224+
- 對於非必需的引用類型屬性,應將其標記為可空(如 `string?`)以避免可空警告
225+
- 對於值類型(如 `int``bool`),如果想保留默認值而非 `null`,不應將其標記為可空
226+
227+
示例:
228+
229+
```csharp
230+
class OptionsBestPractice
231+
{
232+
// 必需選項:使用 required,無需擔心默認值
233+
[Option("input")]
234+
public required string InputFile { get; init; }
235+
236+
// 可選選項:標記為可空類型以避免警告
237+
[Option("output")]
238+
public string? OutputFile { get; init; }
239+
240+
// 需要默認值的選項:使用 set 而非 init
241+
[Option("format")]
242+
public string Format { get; set; } = "json";
243+
244+
// 值類型選項:不需要標記為可空
245+
[Option("count")]
246+
public int Count { get; set; } = 1;
247+
}
248+
```
249+
196250
## 命令處理與謂詞
197251

198252
你可以使用命令處理器模式處理不同的命令(謂詞),類似於`git commit``git push`等。DotNetCampus.CommandLine 提供了多種添加命令處理器的方式:
@@ -241,7 +295,7 @@ internal class ConvertCommandHandler : ICommandHandler
241295
public string? OutputFile { get; init; }
242296

243297
[Option('f', "format")]
244-
public string Format { get; init; } = "json";
298+
public string Format { get; set; } = "json";
245299

246300
public Task<int> RunAsync()
247301
{

0 commit comments

Comments
 (0)