C# 有没有更好的方法来构造这个if语句
这对我来说简直是一团糟,我的思想告诉我必须有更好的办法 我在一个网页上有6个控件C# 有没有更好的方法来构造这个if语句,c#,asp.net,C#,Asp.net,这对我来说简直是一团糟,我的思想告诉我必须有更好的办法 我在一个网页上有6个控件 if (printer_make_1.Text != "" && printer_model_1.Text != "" && printer_make_2.Text != "" && printer_model_2.Text != "" && printer_make_3.Text != "" && printer_model_3.Te
if (printer_make_1.Text != "" && printer_model_1.Text != "" && printer_make_2.Text != "" && printer_model_2.Text != "" && printer_make_3.Text != "" && printer_model_3.Text != "")
{
// Do something
}
做这件事最好/最有效的方法是什么
if(new[] { printer_make_1, printer_model_1 ...}.All(l => l.Text != string.Empty)
{
//do something
}
您可能希望将其拆分,以便更具可读性:
var labels = new[] { printer_make_1, printer_model_1 ... };
if(labels.All(l => l.Text != string.Empty))
{
//do something
}
如果希望提高可读性或在其他地方使用相同的逻辑,可以重构为方法:
public Boolean AllControlsHaveAValue() {
return (printer_make_1.Text != ""
&& printer_model_1.Text != ""
&& printer_make_2.Text != ""
&& printer_model_2.Text != ""
&& printer_make_3.Text != ""
&& printer_model_3.Text != "");
}
那就问问:
if (AllControlsHaveAValue()) {
// do something
}
我通常将该测试放入一个方法中,并调用该方法以使if更易于阅读
private boolean AreAllPrinterFieldsFilled()
{
return (printer_make_1.Text != ""
&& printer_model_1.Text != ""
&& printer_make_2.Text != ""
&& printer_model_2.Text != ""
&& printer_make_3.Text != ""
&& printer_model_3.Text != "");
}
然后在if中:
if (AreAllPrinterFieldsFilled)
{
// Do something
}
有很多方法可以做到这一点——没有一种是优雅的做你(以及你身后的人)最容易理解的事情。 我可能会采取这种方法:
string makeText = String.Concat(printer_make_1.Text, printer_make_2.Text, printer_make_3.Text);
string modelText = String.Concat(printer_model_1.Text, printer_model_2.Text, printer_model_3.Text);
if (makeText.Length != 0 && modelText.Length != 0)
{
// Do something
}
它允许您以后扩展打印机品牌和型号的数量,但不是强类型。重构从您的数据开始:避免
打印机品牌1
,打印机品牌2
class PrinterData
{
public string Make { get; set; }
public string Model { get; set; }
}
PrinterData[] printers = new PrinterData[3]; //or use a List<>
printers[0] = new PrinterData { Make = "PH", Model = "1A" };
...
if (printers.All(p => ! (p.Make == "" || p.Model == "")) )
...
类PrinterData
{
公共字符串Make{get;set;}
公共字符串模型{get;set;}
}
PrinterData[]打印机=新的PrinterData[3]//或者使用列表
打印机[0]=新打印机数据{Make=“PH”,Model=“1A”};
...
if(printers.All(p=>!(p.Make==“| | p.Model==”))
...
Haha,这几乎没有什么可读性了……嗯。当然有办法。这一个确实让我笑了。不过那会管用的。我不认为这是“最好/最有效的方法”。我认为to OP版本更具可读性,可读性创造了可维护性,IMHO使之更好。@C.Dragon76-效率可能更低,但我觉得它更具可读性,并且易于扩展。您的代码可读性很好,几乎可以肯定是正确的。更改可读、正确的代码有什么商业优势吗?如果我不得不多次使用这样的if语句,我肯定会像其他人建议的那样将其转换为一种方法,否则我会将其保留为is@EricLippert除了增进自己的知识,没有什么好处。我确实学到了很多新的方法,到目前为止,我最喜欢的两个选项是方法选项和类选项。在@TimBJames为我编辑之前,它的可读性较差。;)伙计,我希望我能在这件事上给出两个答案=(+1问题不一定是if的结构,也不一定是需要以另一种方式编写,有时用一个可读的方法名来包装它才有意义。这让我想起了无注释编程。@AdamHouldsworth Mmmm…无注释代码:)我想斯波尔斯基不久前写了一篇关于这方面的好文章。@Yuck:有这样一篇:@Yuck是的,这可能是我记得的。我不赞成纯粹的观点,但有时这很有道理。。。最常见的是复杂的if语句。为什么创建几个新字符串只是为了检查几个现有字符串的值?@ChrisFarmer,创建几个字符串很简单。同样,有很多方法可以实现这一点(正如我所说的)。对我来说,这是最容易理解的。我不认为创建几个字符串会导致任何性能问题:)我并不是真的对性能影响有异议。我想我只是同情Eric Lippert对这个问题的评论,这意味着如果它没有损坏,就不要修复它。如果我允许他们填写三种不同的打印机品牌/型号,我会再创建4个属性吗?我对asp.net还很陌生。@Henk:如果你在制作一个类,你也可以使用属性HasValue
,比如public bool HasValue{get{return!(Make.Length==0 | | Model.Length==0)}
没有打印机是一个列表。“我会把它做成一个数组,这样更容易掌握。@Henkholtman你认为哪种方法更好?数组或列表,还是它们如此接近,这是个人的选择?若列表更好,你们知道有并没有一个好的读物可以帮助我更好地理解如何以这种方式使用列表?我只是尽我所能去学习。:)我几乎总是使用列表,但您似乎有一个非常固定的元素数(3),所以数组也可以。
class PrinterData
{
public string Make { get; set; }
public string Model { get; set; }
}
PrinterData[] printers = new PrinterData[3]; //or use a List<>
printers[0] = new PrinterData { Make = "PH", Model = "1A" };
...
if (printers.All(p => ! (p.Make == "" || p.Model == "")) )
...
private bool CheckAllEmpty(params TextBox[] textBoxes)
{
return textBoxes.All(tb => tb.Text != null);
}
private void Foo()
{
...
if (CheckAllEmpty(tb1, tb2, tb3))
{
mbox("tb1, tb2 and tb3 are all empty");
}
else
{
mbox("tb1, tb2 or tb3 isn't empty");
}
...
}