【问题标题】:Using ternary operator: "only assignment, call, increment..."使用三元运算符:“仅赋值、调用、递增……”
【发布时间】:2013-08-20 06:36:14
【问题描述】:

我将动作字典定义为:

var actions = new Dictionary<string, Action<string, string>>();

我把动作放在那里:

actions.Add("default", (value, key) => result.Compare(value, properties[key], Comparers.SomeComparer, key));
...

我正在使用这段代码来运行它:

if (actions.ContainsKey(pair.Key))
{
    actions[pair.Key](pair.Value, pair.Key);
}
else
{
    actions[""](pair.Value, pair.Key);
}

它工作得很好,但我想使用'?符号以使其更短:

actions.ContainsKey(pair.Key) ? actions[pair.Key](pair.Value, pair.Key) : actions[""](pair.Value, pair.Key);

此代码显示错误:

错误 1 ​​只有赋值、调用、递增、递减和新对象 表达式可以用作 声明

actions[pair.Key](pair.Value, pair.Key) 这不是电话吗?我错过了什么吗?是否可以使用'?动作字典的符号?我试图找到一些关于它的东西,但很难找到关于“?”的任何东西。运算符和此错误是因为 '?'被谷歌忽略。

【问题讨论】:

  • 你没有分配任何东西,它真的更短吗?
  • @Sayse 是的,我不是,但我需要做“赋值、调用、递增、递减……”,而我正在调用。我更喜欢这种表示法,但重点是我的好奇心。我真的很想知道,我的电话有什么问题:)
  • 声明 (? : ) 不是调用 - 它是三元运算符,不能单独使用 - 与将 true &amp;&amp; false; 之类的内容放在新行相同。

标签: c# .net


【解决方案1】:

如果你真的必须这样做,你可以试试

actions[actions.ContainsKey(pair.Key) ? pair.Key : ""](pair.Value, pair.Key);

澄清一下,来自: Operator (C# Reference)

条件必须评估为真或假。如果条件为真, first_expression 被评估并成为结果。如果条件是 false,second_expression 被评估并成为结果。只有一个 计算两个表达式中的一个。

这是等价的

int input = Convert.ToInt32(Console.ReadLine());
string classify;

// if-else construction.
if (input < 0)
    classify = "negative";
else
    classify = "positive";

// ?: conditional operator.
classify = (input < 0) ? "negative" : "positive";

【讨论】:

  • 谢谢阿德里安你的解释 == 太好了。
【解决方案2】:

你的电话本身没有问题。表达式actions[pair.Key](pair.Value, pair.Key) 确实是一个调用。不过,这不是编译器抱怨的表达式。编译器指的是整个条件运算符表达式,它既不是赋值、调用、递增、递减,也不是新对象表达式,因此不允许单独作为语句。

替代方案包括:

  • 将表达式的结果分配给另一个变量,使条件只是较大赋值语句的子表达式
  • 将条件分解到索引表达式中,因此整个语句是一个调用,而不是两个单独的调用。
  • 使用两个独立的语句来决定使用哪个键然后调用函数:

    var key = actions.ContainsKey(pair.Key) ? pair.Key : "";
    actions[key](pair.Value, pair.Key);
    

    它仍然避免重复代码,但通过不尝试将所有内容打包到一个复杂的语句中,使内容更易于阅读。

【讨论】:

    【解决方案3】:

    试试这个:

    actions[actions.ContainsKey(pair.Key) ? pair.key : ""](pair.Value, pair.Key);
    

    这将解决您的问题。

    【讨论】:

    • 非常感谢,它帮助了我。
    • 我认为这段代码不应该取代原来的。仅仅因为它是一行代码并不好。
    • 我的朋友为什么不更好?
    • 最好不要使用 ternar 运算符,因为您不会获得任何速度提升,但代码的可读性更差(标准编码实践),以防万一有人接管您的代码,他会更容易阅读 if else then ternar 运算符
    • 避免三元运算符与避免一元运算符一样有意义 - 因为它们的元数而避免任何运算符对我来说没有多大意义
    【解决方案4】:

    ?: Conditional operator 定义为:

    条件运算符 (?:) 根据布尔表达式的值返回两个值之一

    您的操作没有返回值,那么?: 的返回值是什么意思?

    【讨论】:

      【解决方案5】:

      每个“?:”语句都需要分配给某物,这意味着

      actions.ContainsKey(pair.Key) ? actions[pair.Key](pair.Value, pair.Key) : actions[""](pair.Value, pair.Key);
      

      不合法,因为它没有分配任何东西。

      你可以这样做:

      object x = actions.ContainsKey(pair.Key) ? actions[pair.Key](pair.Value, pair.Key) : actions[""](pair.Value, pair.Key);
      

      如果 actions[pair.Key](pair.Value, pair.Key)actions[""](pair.Value, pair.Key); 返回一个值,那将是合法的

      【讨论】:

      • 更准确地说:每个三元表达式都必须返回一些东西
      猜你喜欢
      • 2012-02-14
      • 1970-01-01
      • 2013-06-28
      • 2015-05-23
      • 2018-06-20
      • 2011-07-02
      • 2021-04-29
      • 2021-11-23
      • 2013-12-22
      相关资源
      最近更新 更多