简体   繁体   English

谁能想到一种精巧的方法来减少此嵌套的if-else语句?

[英]Can anyone think of an elegant way of reducing this nested if-else statement?

if (Request.QueryString["UseGroups"] != null)
{
  if (Request.QueryString["UseGroups"] == "True")
  {
    report.IncludeGroupFiltering = true;
  }
  else
  {
    report.IncludeGroupFiltering = false;
  }
}
else
{
  report.IncludeGroupFiltering = false;
}

Simply a single check: 只需一次检查:

report.IncludeGroupFiltering = Request.QueryString["UseGroups"] == "True";

There's no need to evaluate Request.QueryString["UseGroups"] twice - it can only be equal to "True" if it's non-null, and the comparison will work perfectly well (and return false) if it is null. 有没有必要评价Request.QueryString["UseGroups"]两次-它只能是等于“真”,如果它非空,比较将会很好地工作(返回FALSE),如果它

Any solutions still doing two operations are over-complicating matters :) 任何仍在执行两项操作的解决方案会使问题变得更加复杂:)

report.IncludeGroupFiltering = Request.QueryString["UseGroups"] == "True"

\n

report.IncludeGroupFiltering = Request.QueryString["UseGroups"] == "True";
\n

I think Request.QueryString["UseGroups"] == "True" and "True" is a string only , it does not behave like bool. 我认为Request.QueryString["UseGroups"] == "True"和“ True”仅是一个字符串,它的行为不像bool。 So, you can write in a line 所以,你可以写一行

report.IncludeGroupFiltering = string.IsNullOrEmpty(Request.QueryString["UseGroups"])? 
                                false : (Request.QueryString["UseGroups"] == "True");

report.IncludeGroupFiltering = "True" == Request.QueryString["UseGroups"];

Factor out the Request.QueryString["UseGroups"] part to make it clear you want to refer to the same thing, and then it becomes: 分解出Request.QueryString [“ UseGroups”]部分,以使您清楚地要引用同一件事,然后它变成:

string useGroups = Request.QueryString["UseGroups"];
report.IncludeGroupFiltering = (useGroups != null) && (useGroups == "True");
 report.IncludeGroupFiltering = (Request.QueryString["UseGroups"] != null) 
                                && (Request.QueryString["UseGroups"] == "True");

You're doing it basically the way I would. 您基本上按照我的方式进行。 Just remove the redundant inner else: 只需删除多余的内部else:

if(Request.QueryString["USeGroups"] != null)
{
  if(Request.QueryString["UseGroups"] == "True")
    report.IncludeGroupFiltering = true;
}
else report.IncludeGroupFiltering = false;

Maybe this: 也许这样:

report.IncludeGroupFiltering = false;
if (Request.QueryString["UseGroups"] == "True")
    report.IncludeGroupFiltering = true;

What about using TryParse: 关于使用TryParse呢?

bool includeGroupFiltering;
bool throwaway = Boolean.TryParse(Request.QueryString["UseGroups"], out includeGroupFiltering);
report.IncludeGroupFiltering = includeGroupFiltering;

This is how I do this sort of code: 这就是我执行此类代码的方式:

report.IncludeGroupFiltering = false;

if (Request.QueryString["UseGroups"] != null && 
    Request.QueryString["UseGroups"] == "True"       //note that I am not a C# expert - this line /may/ throw an exception if it is indeed null. 
  {
    report.IncludeGroupFiltering = true;
  }
report.IncludeGroupFiltering = ShouldIncludeGroupFiltering(Request.QueryString["UseGroups"])

private boolean ShouldIncludeGroupFiltering(String queryString) {
    return ("True" == queryString)
}

String constants are immutable and atomized, they are also reference objects. 字符串常量是不可变的且是原子化的,它们也是引用对象。 However the result of Request.QueryString["UserGroups"] is a string reference (or a reference to an object that may be implicitly converted to a string...) that may not be atomized, so you cant just compare the references which may be distinct, even if the strings are comparing equal. 但是,Request.QueryString [“ UserGroups”]的结果是一个字符串引用(或对可能隐式转换为字符串的对象的引用...),它可能不会被原子化,因此您不能只比较可能即使字符串比较相等也要区分。

The == operator on pairs of Strings is not comparing references but string contents. 成对的==运算符不是比较引用而是字符串内容。 This means that the Request.QueryString["UserGroups"] will be dereferenced, and this may cause null pointer dereference exceptions. 这意味着Request.QueryString [“ UserGroups”]将被取消引用,这可能导致空指针取消引用异常。 That's why there's a prior test for null (because tests with "reference == null" is NOT dereferencing the reference but actually checking if it's null or not). 这就是为什么要对null进行事先测试的原因(因为使用“ reference == null”的测试不会取消引用的引用,而是实际上检查其是否为null)。

There's a possibility however to avoid the null check: you may use the === operator to just compare the reference, if the result of Request.QueryString["Usergroups"] has been atomized (but it may require allocation and hashing within the static list of atoms, not a good idea if the QueryString is very large. 但是,有可能避免进行空检查:如果Request.QueryString [“ Usergroups”]的结果已被原子化,则可以使用===运算符来比较引用(但可能需要在静态变量中进行分配和哈希处理)原子列表,如果QueryString非常大,则不是一个好主意。

So yes, the best to do is to first cache the Querystring in a local string variable, and perform the two tests: 因此,是的,最好的办法是首先将Querystring缓存在本地字符串变量中,然后执行两个测试:

final string queryString; // cache the string value 
if ((queryString = Request.QueryString["UserGroups"]) != null &&
  queryString == "True") {
   ...
} else {
   ...
}

But given that the bodies of your if/else statement is just to store the result of the if()'s condition, just write this: 但是考虑到您的if / else语句的主体只是为了存储if()条件的结果,只需编写以下代码:

final string queryString; // temporary register caching the non-atomized string reference 
report.IncludeGroupFiltering =
  (queryString = Request.QueryString["UserGroups"]) != null &&
  queryString == "True"; // compares the two strings contents

BUT ONLY IF the Request.QueryString[] contents are already atomized strings, or if their implicit conversion to string return atomized strings, save the string compares and use === instead: 但是仅当Request.QueryString []内容已经是原子化的字符串,或者如果它们对字符串的隐式转换返回原子化的字符串,则保存字符串比较并使用===代替:

final string queryString; // temporary register caching the atomized string reference 
report.IncludeGroupFiltering =
  (queryString = Request.QueryString["UserGroups"]) != null &&
  queryString === "True"; // compares the atomized references

I will not suggest this dangerous assumption here (it's more probable that query results from a remote source will not be atomized, for security/memory reasons, unless the returned value has already been checked. Given your code, I suspect that this is performing validation on returned values from your query, so the result is most probably not atomized: the main reason of your code is to atomize the content of the Query String into a shared boolean value, which will later compare much more easily. 我不会在这里提出这个危险的假设(出于安全/内存原因,除非已检查返回的值,否则很可能远程原子的查询结果不会被原子化。给定代码,我怀疑这是在执行验证)从查询返回的值上,因此结果很可能不会被雾化:代码的主要原因是将查询字符串的内容雾化为共享的布尔值,这以后将更容易进行比较。


Note: I absolutely don't know what is the type of the value or reference returned by Request.QueryString["UserGroups"]. 注意:我绝对不知道Request.QueryString [“ UserGroups”]返回的值或引用的类型是什么。 It may happen that this is an object that implements the "bool operator==(string)" method, or that even returns another type than bool. 这可能是实现“布尔运算符==(字符串)”方法的对象,甚至可能返回布尔类型以外的其他类型。 Storing the returned object in a string variable however will perform its conversion to a string if the object's type is not null (and if the object is compatible, otherwise you'll get an exception). 但是,如果对象的类型不为null(并且该对象兼容,否则将获得异常),将返回的对象存储在字符串变量中将执行其转换为字符串的操作。

You may want to avoid this conversion of the unknown object, if the object itself can compare to a string like "True", with code like this: 如果对象本身可以使用以下代码与“ True”之类的字符串进行比较,则可能要避免这种未知对象的转换:

report.IncludeGroupFiltering =
  Request.QueryString["UserGroups"] != null &&
  // uses object's operator==(string) to compare its contents OR reference.
  Request.QueryString["UserGroups"] == "True";

All this depends on how you declared the QueryString[] array property of your Request object, and if the array contents can be polymorphic (varying type). 所有这些取决于您如何声明Request对象的QueryString []数组属性,以及数组内容是否可以是多态的(可变类型)。 If you know how it's declared, then use exactly the same type for declaring the temporary final register above, to avoid double member access to QueryString from Request, and double indexing of the QueryString array. 如果知道如何声明,请使用完全相同的类型声明上面的临时最终寄存器,以避免从Request对QueryString的双成员访问以及QueryString数组的双索引。

Here, it's impossible to know which code will be the best for you as we don't have all the declarations (C# inherits the same type complexity/ambiguity as C++, with too many implicit conversions and complex inheritance schemes). 在这里,不可能知道哪个代码最适合您,因为我们没有所有的声明(C#继承了与C ++相同的类型复杂性/歧义性,具有太多的隐式转换和复杂的继承方案)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM