在 WPF 开发中,我们经常需要定义布尔类型的依赖属性或附加属性。一个常见的困惑是:布尔属性是否都应该以 Is 开头?
最近在开发一个重置功能时,我遇到了这个问题。我需要为控件添加一个附加属性,用于标记该控件是否应该跳过重置操作。最初我纠结于应该命名为 IgnoreReset 还是 IsResetIgnored,这促使我深入研究了 WPF 和 .NET 的命名规范。
问题场景
假设我们有这样一个需求:
- 界面上有多个输入控件(TextBox、ComboBox 等)
- 点击 Reset 按钮时,需要将这些控件重置为初始状态
- 但某些控件由于业务逻辑要求,不应该被重置
- 我们需要一个附加属性来标记这些”不可重置”的控件
那么,这个布尔类型的属性应该叫什么?
IgnoreReset?IsResetIgnored?SkipReset?IsResetDisabled?
核心原则:语义决定命名
答案是:并不是所有布尔属性都需要 Is 前缀。关键在于这个属性表达的语义。
规则一:描述状态或特征 → 使用 Is 前缀
当布尔属性用于描述对象的当前状态或固有特征时,应该使用 Is 前缀。
WPF 框架中的例子
// UIElement 类
IsEnabled // 控件是否启用
IsVisible // 控件是否可见
IsFocused // 控件是否获得焦点
// TextBox 类
IsReadOnly // 文本框是否只读
// ListBoxItem 类
IsSelected // 列表项是否被选中
// Window 类
IsActive // 窗口是否处于活动状态
特点:
- ✅ 描述”是什么”或”处于什么状态”
- ✅ 通常可以回答 “Is this control [adjective]?” 这样的问题
- ✅ 读起来像自然语言:”Is Enabled?”(是否启用?)
规则二:控制行为或操作 → 不使用 Is 前缀
当布尔属性用于控制行为、配置选项或操作标志时,通常使用动词形式,不加 Is 前缀。
WPF 框架中的例子
// UIElement 类
AllowDrop // 是否允许拖放
Focusable // 是否可获得焦点
ClipToBounds // 是否裁剪到边界
// ScrollViewer 类
CanContentScroll // 内容是否可以滚动
// TextBox 类
AcceptsReturn // 是否接受回车键
AcceptsTab // 是否接受 Tab 键
// Window 类
ShowInTaskbar // 是否在任务栏显示
Topmost // 是否置顶
特点:
- ✅ 描述”做什么”或”如何做”
- ✅ 通常是配置项或开关
- ✅ 更像是指令或许可:”Allow Drop”(允许拖放)
常见的动词前缀
除了不使用前缀,还有一些常见的动词前缀用于布尔属性:
| 前缀 | 含义 | 示例 |
|---|---|---|
Allow |
允许某个操作 | AllowDrop, AllowTransparency |
Can |
是否能够执行 | CanExecute, CanContentScroll |
Enable |
启用某个特性 | EnableViewState, EnableColumnVirtualization |
Show |
是否显示 | ShowInTaskbar, ShowGridLines |
Use |
是否使用 | UseLayoutRounding, UseSystemFocusVisuals |
Ignore |
是否忽略 | IgnoreCase, IgnoreWhitespace |
Skip |
是否跳过 | SkipStoryboardToSeek |
Prevent |
是否阻止 | PreventDefault |
Accept |
是否接受 | AcceptsReturn, AcceptsTab |
回到我们的问题
现在让我们回到文章开头的场景。我们需要一个附加属性来标记控件是否应该跳过重置操作。
分析语义
- 这个属性是配置项,而不是状态
- 它控制行为:告诉重置逻辑”请忽略这个控件”
- 它不是描述控件当前的状态
推荐方案
IgnoreReset // ✅ 最推荐:简洁,语义清晰
其他可选方案
SkipReset // ✅ 简洁,语义清晰
ExcludeFromReset // ✅ 更正式,但稍长
PreventReset // ✅ 也可以,但"防止"的语气略强
不推荐的方案
IsResetIgnored // ❌ 听起来像状态而非配置
IsResetDisabled // ❌ 冗长,且语义略显混乱
IsExcludedFromReset // ❌ 过于冗长
决策流程
当你需要命名一个布尔属性时,可以按照这个流程思考:
开始命名布尔属性
↓
问:这个属性描述的是"状态/特征"还是"行为控制"?
↓
├─→ 状态/特征(是什么?)
│ ↓
│ 使用 Is 前缀
│ 例如:IsEnabled, IsSelected, IsVisible
│
└─→ 行为控制(做什么?如何做?)
↓
使用动词或直接描述
例如:AllowDrop, IgnoreReset, CanExecute
自测问题
通过提问来判断应该使用哪种命名方式:
- “这个控件是否被启用?” →
IsEnabled(状态) - “是否允许在这个控件上拖放?” →
AllowDrop(行为控制) - “是否忽略这个控件的重置操作?” →
IgnoreReset(行为控制) - “这个窗口是否处于活动状态?” →
IsActive(状态) - “是��在任务栏显示这个窗口?” →
ShowInTaskbar(行为控制)
实战案例分析
案例 1:验证控件
// ❌ 不好的命名
IsValidateOnInput
// ✅ 更好的命名(配置)
ValidateOnInput // 是否在输入时验证
// ✅ 用于状态
IsValid // 控件内容是否有效
IsValidating // 是否正在验证
分析:
ValidateOnInput是配置项,控制”何时验证”的行为IsValid是状态,描述”当前是否有效”IsValidating是状态,描述”当前是否正在验证中”
案例 2:自动保存功能
// ❌ 混淆的命名
IsAutoSave
// ✅ 清晰的命名(配置)
EnableAutoSave
AutoSave
// ✅ 如果描述状态
IsAutoSaving // 当前是否正在自动保存
分析:
EnableAutoSave或AutoSave是功能开关,属于配置IsAutoSaving是当前正在进行的动作,属于状态
案例 3:日志记录
// 配置项:是否启用详细日志
EnableVerboseLogging // ✅
VerboseLogging // ✅
IsVerboseLogging // ❌ 容易混淆
// 状态:是否正在记录日志
IsLogging // ✅ 当前是否正在记录
案例 4:动画控制
// 配置项:是否启用动画
EnableAnimation // ✅
UseAnimation // ✅
IsAnimationEnabled // ❌ 冗长且别扭
// 状态:是否正在播放动画
IsAnimating // ✅
IsAnimationPlaying // ✅
案例 5:缓存策略
// 配置项:是否使用缓存
EnableCaching // ✅
UseCache // ✅
IsCacheEnabled // ❌ 冗长
// 状态:缓存是否存在
IsCached // ✅ 数据是否已缓存
IsCaching // ✅ 是否正在缓存
语义对比表
为了更清晰地说明差异,这里提供一个对比表:
| 场景 | 状态/特征命名(用 Is) | 行为控制命名(不用 Is) |
|---|---|---|
| 控件可用性 | IsEnabled |
EnableControl |
| 控件可见性 | IsVisible |
ShowControl |
| 选中状态 | IsSelected |
AllowSelection |
| 只读状态 | IsReadOnly |
PreventEditing |
| 验证 | IsValid, IsValidating |
ValidateOnInput, EnableValidation |
| 拖放 | IsBeingDragged |
AllowDrop |
| 重置 | IsReset |
IgnoreReset |
| 焦点 | IsFocused |
Focusable |
总结与建议
核心要点
-
Is前缀用于状态和特征- 描述”是什么”或”处于什么状态”
- 通常是只读或由系统控制的属性
- 例如:
IsEnabled,IsSelected,IsFocused
-
行为控制不使用
Is前缀- 描述”做什么”或”如何做”
- 通常是用户可配置的选项
- 使用动词或直接描述
- 例如:
AllowDrop,IgnoreReset,CanExecute
-
命名应该符合自然语言习惯
IsEnabled✅ → “Is this control enabled?”AllowDrop✅ → “Allow drop on this control?”IsAllowDrop❌ → 听起来很别扭
-
保持一致性
- 在同一项目中保持命名风格一致
- 遵循团队编码规范
- 与 WPF 框架的命名习惯保持一致
推荐的命名模式
| 场景 | 推荐命名 | 示例 |
|---|---|---|
| 控件状态 | Is + 形容词 |
IsEnabled, IsVisible |
| 正在进行的动作 | Is + 动词现在分词 |
IsLoading, IsProcessing |
| 操作许可 | Allow + 动词 |
AllowDrop, AllowEdit |
| 能力判断 | Can + 动词 |
CanExecute, CanScroll |
| 功能开关 | Enable + 名词 |
EnableCaching, EnableLogging |
| 使用特性 | Use + 名词 |
UseAnimation, UseCache |
| 显示控制 | Show + 名词 |
ShowInTaskbar, ShowGridLines |
| 忽略/跳过 | Ignore/Skip + 名词 |
IgnoreReset, SkipValidation |
| 接受输入 | Accept + 名词 |
AcceptsReturn, AcceptsTab |
| 简单开关 | 直接名词/形容词 | Focusable, Topmost |
命名检查清单
在命名布尔属性前,问自己这些问题:
- 这个属性描述的是状态还是行为控制?
- 用自然语言读出来是否顺畅?
- 如果是状态,使用
Is前缀后是否自然? - 如果是行为控制,使用动词前缀是否更清晰?
- 是否与项目中其他类似属性的命名风格一致?
- 是否与 WPF 框架的命名习惯一致?
- 默认值是
false时,属性名是否仍然合理?
特殊情况
有些情况下,命名可能存在灰色地带:
// 这两种都可以接受
IsReadOnly // 强调状态
ReadOnly // 简洁直接
// 选择建议:
// - 如果框架中类似属性使用 Is,则跟随框架
// - 如果是自定义属性,保持项目内一致即可
结语
布尔属性的命名看似简单,实则体现了对 API 设计的深入理解。Is 前缀不是布尔属性的必需品,而是一个用于区分”状态”和”行为”的语义工具。
记住核心原则:让代码像说话一样自然。
- 当你读到
IsEnabled时,你知道这是在描述状态 - 当你读到
AllowDrop时,你知道这是在配置行为 - 当你读到
IgnoreReset时,你知道这是一个控制开关
这种语义上的清晰性,正是优秀 API 设计的标志。
回到文章开头的问题,对于”标记控件是否跳过重置”的附加属性,IgnoreReset 是最佳选择。它简洁、清晰,完美地表达了”这是一个行为控制配置项”的语义。
希望这篇文章能帮助你在未来的开发中,更自信地为布尔属性命名。







