C# 这个逻辑可以简化吗?

C# 这个逻辑可以简化吗?,c#,logic,isenabled,isnullorempty,C#,Logic,Isenabled,Isnullorempty,我有两组控件 第一个包含3个名为a、b和c的文本框。它们可以同时启用或禁用 第二组包含两个文本框(d和e)。一次仅启用一个 现在,我有一个布尔变量(名为ok),如果: a、b和c中至少有一个已启用并包含文本 已启用的第二个组的文本框包含文本 如果不包含文本,则无法启用任何选项 我想在一次通话中查看它 以下是我得到的: bool ok = ( ( ( (!a.IsEnabled || (a.IsEnabled &a

我有两组控件

第一个包含3个名为a、b和c的文本框。它们可以同时启用或禁用

第二组包含两个文本框(d和e)。一次仅启用一个

现在,我有一个布尔变量(名为ok),如果:

  • a、b和c中至少有一个已启用并包含文本
  • 已启用的第二个组的文本框包含文本
  • 如果不包含文本,则无法启用任何选项
我想在一次通话中查看它

以下是我得到的:

bool ok =
(
    (
        (
            (!a.IsEnabled ||
                (a.IsEnabled && !String.IsNullOrWhiteSpace(a.Text))) &&
            (!b.IsEnabled ||
                (b.IsEnabled && !String.IsNullOrWhiteSpace(b.Text))) &&
            (!c.IsEnabled ||
                (c.IsEnabled && !String.IsNullOrWhiteSpace(c.Text))) &&
            (a.IsEnabled || b.IsEnabled || c.IsEnabled)
        )
    ) &&
    (
        (!d.IsEnabled ||
            (d.IsEnabled && !String.IsNullOrWhiteSpace(d.Text))) &&
        (!f.IsEnabled ||
            (f.IsEnabled && !String.IsNullOrWhiteSpace(f.Text)))
    )
);
这对眼睛来说很重,你知道怎么简化吗?

是的

!a.IsEnabled || (a.IsEnabled && !String.IsNullOrWhiteSpace(a.Text))
可以简化为

!a.IsEnabled || !String.IsNullOrWhiteSpace(a.Text)

为什么不将所有控件粘贴到一个列表中,并使用LINQ查询它们呢

var group1 = new[] { a, b, c };
var group2 = new[] { d, e };
var all = group1.Concat(group2);
// assuming all controls are the same or implement the same interface
Func<ControlType, bool> enabledAndNotEmpty = (x) => {
    return x.IsEnabled && !String.IsNullOrWhiteSpace(x.Text);
};
Func<ControlType, bool> enabledAndEmpty = (x) => {
    return x.IsEnabled && String.IsNullOrWhiteSpace(x.Text);
};
var ok = group1.Any(enabledAndNotEmpty) && // a, b or c is enabled & not empty
         group2.Any(enabledAndNotEmpty) && // d or e is enabled & not empty
         !all.Any(enabledAndEmpty); // none of the above are enabled & empty
var group1=new[]{a,b,c};
var group2=新[]{d,e};
var all=组1.Concat(组2);
//假设所有控件都相同或实现相同的接口
Func enablednotempty=(x)=>{
返回x.IsEnabled&&!String.IsNullOrWhiteSpace(x.Text);
};
Func enabledAndEmpty=(x)=>{
返回x.IsEnabled&&String.IsNullOrWhiteSpace(x.Text);
};
var ok=group1.Any(enablednotempty)&&//a、b或c已启用且不为空
组2.Any(enablednotempty)&&//d或e已启用且不为空
!all.Any(enabledAndEmpty);//以上各项均未启用&为空

您可以通过添加助手扩展方法简化对逻辑的处理:

private static bool IsDisabledOrNotEmpty(this TextBox tb) {
    return !tb.IsEnabled || !String.IsNullOrWhiteSpace(tb.Text);
}
现在,您可以按如下方式重写逻辑:

bool ok =
    a.IsDisabledOrNotEmpty()
&&  b.IsDisabledOrNotEmpty()
&&  c.IsDisabledOrNotEmpty()
&&  (a.IsEnabled || b.IsEnabled || c.IsEnabled)
&&  d.IsDisabledOrNotEmpty()
&&  f.IsDisabledOrNotEmpty();

这与问题中的代码不太一样:想象一下
a
b
d
被启用-然后
a
d
可以包含非空文本,而
b
可以是空的,并且您的代码仍然会将
ok
设置为
true
,即使问题中的代码不允许启用的文本框为空。呃,你想让我有那么多调用来实现新变量吗p@O.R.Mapper也许我误解了这个问题,但是当我阅读需求时,两个组都必须至少有一个控件同时启用而不是空的-上面的代码给出了这一点。Kilazur我很难再调用它了,它正在将所有控件移动到一个可查询的数组中,如果数组增长,这将更易于维护/更新。编辑了我的问题,我确实错过了一个标准。这只会简化每行代码,您仍然需要为每个控件编写一个检查。这不应该是
IsDisabledOrNotEmpty