C# 有人能想出一种优雅的方法来减少这个嵌套的if-else语句吗?

C# 有人能想出一种优雅的方法来减少这个嵌套的if-else语句吗?,c#,C#,report.IncludeGroupFiltering=Request.QueryString[“UseGroups”]=“True”; 只需一次检查: report.IncludeGroupFiltering = Request.QueryString["UseGroups"] == "True"; 无需对Request.QueryString[“UseGroups”]求值两次-如果它不为null,则只能等于“True”,如果它为null,则比较将非常有效(并返回false) 任何仍然执行两


report.IncludeGroupFiltering=Request.QueryString[“UseGroups”]=“True”;

只需一次检查:

report.IncludeGroupFiltering = Request.QueryString["UseGroups"] == "True"; 无需对Request.QueryString[“UseGroups”]求值两次-如果它不为null,则只能等于“True”,如果它为null,则比较将非常有效(并返回false)


任何仍然执行两个操作的解决方案都会使问题变得过于复杂:)

您基本上按照我的方式执行。只需移除冗余的内部组件即可:

report.IncludeGroupFiltering = Request.QueryString["UseGroups"] == "True";
也许是这样:

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

report.IncludeGroupFiltering=“True”==Request.QueryString[“UseGroups”]

使用TryParse如何:

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

将Request.QueryString[“UseGroups”]部分分解出来,以明确表示您希望引用相同的内容,然后它将变成:

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

我认为
Request.QueryString[“UseGroups”]=“True”
和“True”只是一个字符串,它的行为不像bool。 所以 你可以写一行

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

我就是这样编写这种代码的:

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

字符串常量是不可变的和原子化的,它们也是引用对象。但是,Request.QueryString[“UserGroups”]的结果是一个字符串引用(或对可能隐式转换为字符串的对象的引用…),它可能不会被原子化,因此您不能只比较可能不同的引用,即使字符串比较相等

字符串对上的==运算符不是比较引用,而是比较字符串内容。这意味着Request.QueryString[“UserGroups”]将被取消引用,这可能会导致空指针取消引用异常。这就是为什么之前有一个null测试(因为使用“reference==null”的测试不是取消引用,而是实际检查它是否为null)

但是,也有可能避免空检查:如果Request.QueryString[“Usergroups”]的结果已原子化,则可以使用===运算符仅比较引用(但可能需要在静态原子列表中进行分配和散列,如果QueryString非常大,这不是一个好主意)

因此,最好的做法是首先将Querystring缓存在本地字符串变量中,然后执行两个测试:

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;
  }
但鉴于if/else语句的主体只是存储if()条件的结果,只需编写以下代码:

final string queryString; // cache the string value 
if ((queryString = Request.QueryString["UserGroups"]) != null &&
  queryString == "True") {
   ...
} else {
   ...
}
但仅当Request.QueryString[]内容已经是原子化字符串,或者如果它们对字符串的隐式转换返回原子化字符串,则保存字符串比较并改用===:

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
我不会在这里提出这种危险的假设(出于安全/内存原因,远程源的查询结果很可能不会原子化,除非已检查返回值。鉴于您的代码,我怀疑这是在对查询返回值执行验证,因此结果很可能没有原子化:代码的主要原因是要原子化将查询字符串的内容转换为一个共享的布尔值,以后比较起来会容易得多


注意:我完全不知道Request.QueryString[“UserGroups”]返回的值或引用的类型。可能这是一个实现“bool操作符==(字符串)”的对象方法,甚至返回bool以外的另一种类型。但是,如果对象的类型不为null(并且如果对象兼容,否则将获得异常),则将返回的对象存储在字符串变量中将执行其到字符串的转换

如果对象本身可以与类似“True”的字符串进行比较,则您可能希望避免对未知对象进行这种转换,代码如下:

final string queryString; // temporary register caching the atomized string reference 
report.IncludeGroupFiltering =
  (queryString = Request.QueryString["UserGroups"]) != null &&
  queryString === "True"; // compares the atomized references
所有这些都取决于您如何声明请求对象的QueryString[]数组属性,以及数组内容是否可以是多态的(不同类型)。如果您知道它是如何声明的,那么请使用与上面声明临时最终寄存器完全相同的类型,以避免从请求中对QueryString进行双成员访问,以及对QueryString数组进行双索引


这里,不可能知道哪个代码对你来说是最好的,因为我们没有所有的声明(C++继承了与C++相同的类型复杂度/歧义,有太多隐式转换和复杂的继承方案)。.

这是可行的,因为索引器返回null,如果找不到键,则不会引发异常。如果此解决方案会引发异常,则原始代码也会引发异常,因此行为将是相同的。啊,所以请求.QueryString[“SomethingNotThere”]如果我尝试比较,不会抛出对象引用异常吗?我一定把它的行为与ViewData的行为混淆了[“未定义”]OP要求一个优雅的解决方案。我们不能进一步减少代码行吗?有时我无法理解为什么我的答案没有被提升,尽管这是第一次——现在我自己也在提升投票(我甚至没看名字!)这将失败。如果UseGroups为非空,但不是“True”然后IncludeGroupFiltering从未设置。True。我通常假设bool设置为false,然后更新为True-在这种情况下,最后一行也可以省略。这可能是一个无效的假设。我实际上没有尝试运行该代码,但当您最初将正确的True或false值分配给inc时,它会出现这种情况ludeGroupFiltering,您将立即用表示解析是否成功的true/false覆盖它。因此,如果您传入“true”或“false”,您将以true结束.@stack,你是对的,意味着要使用一次性变量。更新。在比较
string
实例时,不需要检查
null
。你的代码表明你不了解布尔类型。你很少(如果有)需要做“if(something==true)somethingElse=true;@Ed,他没有做if”(something==true),他在做if(something==true)。这是避免调用
e的一种回忆
final string queryString; // cache the string value 
if ((queryString = Request.QueryString["UserGroups"]) != null &&
  queryString == "True") {
   ...
} else {
   ...
}
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
final string queryString; // temporary register caching the atomized string reference 
report.IncludeGroupFiltering =
  (queryString = Request.QueryString["UserGroups"]) != null &&
  queryString === "True"; // compares the atomized references
report.IncludeGroupFiltering =
  Request.QueryString["UserGroups"] != null &&
  // uses object's operator==(string) to compare its contents OR reference.
  Request.QueryString["UserGroups"] == "True";
report.IncludeGroupFiltering = ShouldIncludeGroupFiltering(Request.QueryString["UseGroups"])

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