为什么三元运算符不替换if-else

str*_*372 3 c#

我遇到了一个小问题和知识鸿沟

我发现有时使用If-Else样式太样板了,想用elvis-operator代替它,例如:

Dictionary<string, List<List<int>> VarsWithInfo;
Run Code Online (Sandbox Code Playgroud)

要替换:

if (VarsWithInfo.ContainsKey(ruleVar))
    {
        VarsWithInfo[ruleVar] = new List<List<int>> { NestingBlocks };
    }
else
    {
        VarsWithInfo[ruleVar].Add(NestingBlocks);
    }
Run Code Online (Sandbox Code Playgroud)

接着就,随即:

VarsWithInfo.ContainsKey(ruleVar) ?
    VarsWithInfo[ruleVar] = new List<List<int>> { NestingBlocks } :
    VarsWithInfo[ruleVar].Add(NestingBlocks);
Run Code Online (Sandbox Code Playgroud)

我知道在这种情况下与ternar运算符的连线太长,但我想知道主要原因。谢谢。

can*_*on7 11

条件运算符?:(通常称为三元条件运算符)对布尔表达式求值,并根据布尔表达式的取值为true或false返回两个表达式之一的求值结果

从MSDN

三元运算符始终返回一个值。在表达式中x = a ? b : c,如果atrue,则将分配bto 的值x,否则将分配cto 的值x

因此,两个b和都c必须是产生值的表达式,并且两个值都必须是同一类型。

无论是VarsWithInfo[ruleVar] = new List<List<int>> { NestingBlocks }也不VarsWithInfo[ruleVar].Add(NestingBlocks)是表达式,并没有返回值。因此,它们不能用于三元组。


我假设您的代码应该是:

if (!VarsWithInfo.ContainsKey(ruleVar))
{
    VarsWithInfo[ruleVar] = new List<List<int>> { NestingBlocks };
}
else
{
    VarsWithInfo[ruleVar].Add(NestingBlocks);
}
Run Code Online (Sandbox Code Playgroud)

一种常见的编写方式是:

if (!VarsWithInfo.TryGetValue(ruleVar, out var list))
{
    list = new List<List<int>>();
    VarsWithInfo[ruleVar] = list;
}
list.Add(NestingBlocks);
Run Code Online (Sandbox Code Playgroud)

这样可以避免重复的字典查找(即调用VarsWithInfo.ContainsKey(ruleVar),然后从读取VarsWithInfo[ruleVar])。