C# 在为循环编写稍微不同的代码时,如何停止重复自己的操作?
我有这些选择和迭代语句。我觉得我做错了什么;我觉得自己重复的太多了,有些地方真的可以优化 问题:如何优化多个稍微不同的循环,使之成为“更好”的循环 以下是代码(请注意,周围的函数适用于每0.5秒“滴答”一次的计时器):C# 在为循环编写稍微不同的代码时,如何停止重复自己的操作?,c#,C#,我有这些选择和迭代语句。我觉得我做错了什么;我觉得自己重复的太多了,有些地方真的可以优化 问题:如何优化多个稍微不同的循环,使之成为“更好”的循环 以下是代码(请注意,周围的函数适用于每0.5秒“滴答”一次的计时器): 您可以使用LINQ消除所有这些循环。 请注意,您可以简单地使用FirstOrDefault,而不是中断循环: 例如,第一个循环: foreach (HtmlElement elem in browser.Document.GetElementsByTag("a"))
您可以使用LINQ消除所有这些循环。
请注意,您可以简单地使用
FirstOrDefault
,而不是中断循环:
例如,第一个循环:
foreach (HtmlElement elem in browser.Document.GetElementsByTag("a"))
{
if (elem.InnerText == "hey")
{
elem.InnerText = "blabla";
break;
}
}
可替换为:
var elem = browser.Document.GetElementsByTag("a").FirstOrDefault(e => e.InnerText == "hey");
if(elem != null)
{
elem.InnerText = "blabla";
}
同样,您也可以使用LINQ替换其他循环:
foreach (HtmlElement elem in browser.Document.GetElementsByTag("button"))
{
if (elem.InnerText == "clickMe")
{
step = 1;
break;
}
}
可替换为:
var elem = browser.Document.GetElementsByTag("button").FirstOrDefault(e => e.InnerText == "clickMe");
if(elem != null)
{
step = 1;
}
var names = new string[] {"something", "notme", "notyou", "notthat", "theone"};
browser.Document.GetElementsByTag("div").FirstOrDefault(e => names.Contains(e.GetAttribute("name"))?.Destroy;
这个巨大的循环:
foreach (HtmlElement elem in browser.Document.GetElementsByTag("div"))
{
if (elem.GetAttribute("name") == "something")
{
elem.Destroy;
break;
}
if (elem.GetAttribute("name") == "notme")
{
elem.Destroy;
break;
}
if (elem.GetAttribute("name") == "notyou")
{
elem.Destroy;
break;
}
if (elem.GetAttribute("name") == "notthat")
{
elem.Destroy;
break;
}
if (elem.GetAttribute("name") == "theone")
{
elem.Destroy;
break;
}
}
可替换为:
var elem = browser.Document.GetElementsByTag("button").FirstOrDefault(e => e.InnerText == "clickMe");
if(elem != null)
{
step = 1;
}
var names = new string[] {"something", "notme", "notyou", "notthat", "theone"};
browser.Document.GetElementsByTag("div").FirstOrDefault(e => names.Contains(e.GetAttribute("name"))?.Destroy;
注意,我使用了字符串数组的Contains方法,而不是代码中的所有条件
等等
此外,我会采纳Tim的建议,将
步骤1
,步骤2
等更改为具有有意义名称的不同方法。我会用这些代码做一些不同的事情:
打破常规
你的timer1\u tick
方法做了很多事情。通常我不喜欢随意地将代码分解成小方法,但我认为这很适合这里。此外,如果。。。否则,如果…structure,则更适合使用开关
因此,代码的一般结构如下所示:
public void FirstStep()
{
//...
}
public void SecondStep()
{
//...
}
public void ThirdStep()
{
//...
}
public void timer1_tick()
{
switch(step)
{
case 1:
FirstStep();
break;
case 2:
SecondStep();
break;
case 1:
ThirdStep();
break;
}
}
foreach(var elem in GetElementByTagAndContent("a", "hey))
{
// Do Logic...
}
public void FirstStep()
{
foreach (HtmlElement elem in GetElementByTagAndContent("a", "hey"))
{
elem.InnerText = "blabla";
}
foreach (HtmlElement elem in GetElementByTagAndContent("button", "clickMe"))
{
step = 1;
}
}
public void SecondStep()
{
switch (elem.GetAttribute("name"))
{
case "A":
case "B":
case "C":
case "D":
elem.Destroy();
break;
}
step = 2;
}
public void ThirdStep()
{
foreach (HtmlElement elem in GetElementByTagAndContent("div", "ClickMeNow"))
{
elem.InnerHtml = "/Done";
step = 3;
}
foreach (HtmlElement elem in GetElementByTagAndContent("a", "linkit"))
{
elem.getAttribute("href") = "www.google.com";
step = 3;
}
}
public void timer1_tick()
{
switch(step)
{
case 1:
FirstStep();
break;
case 2:
SecondStep();
break;
case 1:
ThirdStep();
break;
}
}
public IEnumerable<HtmlElement> GetElementByTagAndContent(string tag, string content)
{
foreach (HtmlElement elem in browser.Document.GetElementsByTag(tag))
{
if (elem.InnerText == content)
yield return elem
}
}
改进foreach
接下来,让我们处理for-each循环。在第一步和第三步中,您的结构始终相同:
foreach (HtmlElement elem in browser.Document.GetElementsByTag("<<Selector>>"))
{
if (elem.InnerText == "<<Selector>>")
{
// Do logic...
}
}
重构第二步
最后,在第二步中,您将执行一系列只检查元素名称的if
s。而且,它们都做相同的动作。这里的switch
语句非常经典
switch (elem.GetAttribute("name"))
{
case "A":
case "B":
case "C":
case "D":
elem.Destroy();
break;
}
最终产品
在所有这些之后,您的代码应该更像这样:
public void FirstStep()
{
//...
}
public void SecondStep()
{
//...
}
public void ThirdStep()
{
//...
}
public void timer1_tick()
{
switch(step)
{
case 1:
FirstStep();
break;
case 2:
SecondStep();
break;
case 1:
ThirdStep();
break;
}
}
foreach(var elem in GetElementByTagAndContent("a", "hey))
{
// Do Logic...
}
public void FirstStep()
{
foreach (HtmlElement elem in GetElementByTagAndContent("a", "hey"))
{
elem.InnerText = "blabla";
}
foreach (HtmlElement elem in GetElementByTagAndContent("button", "clickMe"))
{
step = 1;
}
}
public void SecondStep()
{
switch (elem.GetAttribute("name"))
{
case "A":
case "B":
case "C":
case "D":
elem.Destroy();
break;
}
step = 2;
}
public void ThirdStep()
{
foreach (HtmlElement elem in GetElementByTagAndContent("div", "ClickMeNow"))
{
elem.InnerHtml = "/Done";
step = 3;
}
foreach (HtmlElement elem in GetElementByTagAndContent("a", "linkit"))
{
elem.getAttribute("href") = "www.google.com";
step = 3;
}
}
public void timer1_tick()
{
switch(step)
{
case 1:
FirstStep();
break;
case 2:
SecondStep();
break;
case 1:
ThirdStep();
break;
}
}
public IEnumerable<HtmlElement> GetElementByTagAndContent(string tag, string content)
{
foreach (HtmlElement elem in browser.Document.GetElementsByTag(tag))
{
if (elem.InnerText == content)
yield return elem
}
}
public void FirstStep()
{
foreach(GetElementByTagAndContent(“a”、“hey”)中的HtmlElement元素)
{
elem.InnerText=“blabla”;
}
foreach(GetElementByTagAndContent(“按钮”、“单击我”)中的HtmlElement元素)
{
步骤=1;
}
}
公开作废第二步()
{
开关(elem.GetAttribute(“名称”))
{
案例“A”:
案例“B”:
案例“C”:
案例“D”:
元素Destroy();
打破
}
步骤=2;
}
第三步()的公开无效
{
foreach(GetElementByTagAndContent(“div”、“ClickMeNow”)中的HtmlElement元素)
{
elem.InnerHtml=“/Done”;
步骤=3;
}
foreach(GetElementByTagAndContent(“a”、“linkit”)中的HtmlElement元素)
{
elem.getAttribute(“href”)=“www.google.com”;
步骤=3;
}
}
公共无效计时器1_tick()
{
开关(步骤)
{
案例1:
第一步();
打破
案例2:
第二步();
打破
案例1:
第三步();
打破
}
}
公共IEnumerable GetElementByTagAndContent(字符串标记,字符串内容)
{
foreach(browser.Document.GetElementsByTag(标记))中的HtmlElement元素
{
if(elem.InnerText==内容)
收益率要素
}
}
希望这有帮助请格式化代码,它不可读this@EpicKip怎样?我只是直接写了出来,结果是这样的。顺便说一句,我是新来的:)@sdsadasd
你会觉得有什么不对劲
很主观。正如Manfred所说,通过缩进代码,您可以使其可读。^重构的第一步应该是为每个步骤提取具有有意义名称的方法。步骤本身应该是一个enum
(具有有意义的名称)而不是int
。您可以通过在foreach中进行过滤(因此没有if)使其变得更小,例如:foreach(browser.Document.GetElementsByTag(“a”)。其中(a=>a.InnerText==“Hey”)
您的最终语句不正确,无法写入null条件运算符返回的条件访问表达式-它只能用于读取或删除querying@LordWilmore我不确定你指的是什么陈述,因为你发表评论时我正在编辑答案。你能说得更具体一点吗?关于C#6中空条件运算符的评论完全正确。我本来打算在午餐时开始键入答案,但这几乎涵盖了它-将方法分解为关键的离散元素是关键