我正在检查新名称是否已存在。
代码1
if(cmbxExistingGroups.Properties.Items.Cast<string>().ToList().Exists(txt => txt==txtNewGroup.Text.Trim())) {
MessageBox.Show("already exists.", "Add new group");
}
否则我可以写:
代码2
foreach(var str in cmbxExistingGroups.Properties.Items)
{
if(str==txtNewGroup.Text) {
MessageBox.Show("already exists.", "Add new group");
break;
}
}
我写了这两篇文章,并认为我在开发代码1中的语言功能。
......是的:他们都为我工作......我想知道表现: - /
答案 0 :(得分:15)
我很欣赏第一个样本的聪明(假设它有效),但第二个样本对于必须维护代码的下一个人来说要容易得多。
答案 1 :(得分:11)
有时候只是一点压痕会让世界变得不同:
if (cmbxExistingGroups.Properties.Items
.Cast<string>().ToList()
.Exists
(
txt => txt==txtNewGroup.Text.Trim()
))
{
MessageBox.Show("already exists.", "Add new group");
}
由于您使用了List&lt; String&gt;,因此您可以删除Exists谓词并使用Contains ...在使用唯一值比较复杂对象时使用Exists。
答案 2 :(得分:6)
之前我引用过它,但我会再次这样做:
编写代码,好像维护它的人是杀人狂 谁知道你住在哪里。
答案 3 :(得分:2)
会
cmbxExistingGroups.Properties.Items.Contains(text)
不能正常工作?
答案 4 :(得分:2)
这里有一些问题:
1)两位代码没有做同样的事情 - 第一个寻找修剪版本的txtNewGroup,第二个只寻找txtNewGroup
2)调用ToList()没有意义 - 只会降低效率
3)使用带有谓词的存在是过度的 - 包含就是你需要的所有
所以,第一个很容易归结为:
if (cmbxExistingGroups.Properties.Items.Cast<string>.Contains(txtNewGroup.Text))
{
// Stuff
}
我可能会创建一个变量来为“cmbxExistingGroups.Properties.Items.Cast”提供一个有意义的简单名称 - 但是我会说它比显式的foreach循环更容易理解。
答案 5 :(得分:2)
第一个代码位没问题,除了调用Enumerable.ToList()
和List<T>.Exists()
之外,你应该只调用Enumerable.Any()
- 它做了一个懒惰的评估,因此它永远不会分配内存List<T>
,它将停止枚举cmbxExistingGroups.Properties.Items
并将其投放到string
。此外,从该谓词内部调用修剪意味着它对于它所查看的每个项目都会发生。最好将其移到外部范围:
string match = txtNewGroup.Text.Trim();
if(cmbxExistingGroups.Properties.Items.Cast<string>().Any(txt => txt==match)) {
MessageBox.Show("already exists.", "Add new group");
}
答案 6 :(得分:1)
编码的冗长并不总是坏事。我比第一个代码片段更喜欢第二个代码片段。想象一下你必须维护(甚至改变第一个例子的功能)......嗯。
答案 7 :(得分:1)
好吧,如果是我,那将是2的变化。总是比单线更喜欢可读性。此外,始终提取方法以使其更清晰。
您的通话代码变为
if( cmbxExistingGroups.ContainsKey(txtNewGroup.Text) )
{
MessageBox.Show("Already Exists");
}
如果为组合框定义扩展方法
public static class ComboBoxExtensions
{
public static bool ContainsKey(this ComboBox comboBox, string key)
{
foreach (string existing in comboBox.Items)
{
if (string.Equals(key, existing))
{
return true;
}
}
return false;
}
}
答案 8 :(得分:1)
首先,它们并不等同。第一个示例对txtNewSGroup.Text.Trim()进行检查,第二个示例忽略修剪。此外,第一个将所有内容转换为字符串,而第二个使用从迭代器中发出的任何内容。我认为这是一个对象,或者你不需要第一名的演员阵容。
所以,公平地说,与LINQ风格的第二个样本最接近的是:
if (mbxExistingGroups.Properties.Items.Cast<string>().Contains(txtNewGroup.Text)) {
...
}
这不是太糟糕。但是,既然你似乎正在使用旧式IEnumerable而不是新的IEnumerable&lt; T&gt;,为什么我们不给你另一种扩展方法:
public static Contains<T>(this IEnumerable e, T value) {
return e.Cast<T>().Contains(value);
}
现在我们有:
if (mbxExistingGroups.Properties.Items.Contains(txtNewGroup.Text)) {
...
}
这是非常易读的IMO。
答案 9 :(得分:0)
我同意,继续使用第二个,因为对于任何其他人来说,维护它会更容易,当你在6-12个月内回到那个时,记住你在做什么会更容易。
答案 10 :(得分:0)
它们都适合我..我对性能感到惊讶
我看到没有人读过这个问题:)我想我看到你在做什么(我不使用这种语言)。第一个尝试生成列表并一次性测试它。第二个进行显式迭代,如果它在早期发现重复,可以“短路”自身(提前退出)。问题在于,由于语言的实施,“一下子”是否更有效率。
答案 11 :(得分:0)
这两个中的第二个会表现得更好,而且它的表现与使用Contains的其他人的样本相同。
第一个使用额外修剪的原因。加上转换为列表。所以它迭代一次进行转换,然后再次开始检查使用exists,并且每次都进行修剪,但如果找到则会退出迭代。第二个开始迭代一次,没有修剪,如果找到则退出。
所以简而言之,你的问题的答案是第二个表现要好得多。
答案 12 :(得分:0)
从表现的角度来看:
txtNewGroup.Text.Trim()
在循环之外进行控制交互/字符串操作 - 一次,而不是n次。
答案 13 :(得分:-1)
我想在WTF的每分钟刻度上,第一个将脱离图表。计算点数,每行超过两个是一个潜在的问题