【问题标题】:c# If else shorthandc# if else 简写
【发布时间】:2014-09-22 09:50:24
【问题描述】:

在 c# 中我可以用速记来做这样的事情吗?

 bool validName = true;
 if (validName)
 {
     name = "Daniel";
     surname = "Smith";
 }
 else
 {
     MessageBox.Show("Invalid name");
 }

我只是想知道类似的事情是否会起作用,但在这个确切的场景中,我知道如果我做了 name = validName ,你可以分配值? “丹尼尔”:“无效”,但我只是想知道我是否可以执行以下操作?

     validName ? 
     {
         name = "Daniel";
         surname = "Smith";
     } 
     : 
     {
         MessageBox.Show("Invalid name");
     }

【问题讨论】:

  • if/else 非常简短,语义清晰。即使有办法做到这一点(我对此表示怀疑),我还是建议坚持使用 if/else。
  • 您的第二个版本“更短”如何?它是相同数量的行、相同的结构、相同数量的运算符。一两次击键真的那么难吗?
  • 这是你工作了 20 分钟然后意识到你只是浪费了 20 分钟的事情之一。
  • 如果这里的动机只是为了聪明,那么您可能会从这句话中受益……“调试的难度是一开始编写代码的两倍。因此,如果您将代码编写为尽可能聪明,根据定义,你不够聪明,无法调试它。” ——布赖恩·克尼汉

标签: c# lambda shorthand-if


【解决方案1】:

滥用 lambda 语法和类型推断:

(validName
    ? (Action)
        (() =>
            {
                name = "Daniel";
                surname = "Smith";
            })
      : () =>
           {
                MessageBox.Show("Invalid name");
           })();

我知道,并不是真正的答案。 if 语句要好得多:显然这种语法可读性较差,更重要的是它具有不同的运行时行为,并且由于 lambda 表达式创建的潜在闭包可能导致意外的副作用。

语法也有点神秘。它首先创建两个Action 对象,然后?: 运算符在它们之间进行选择,最后执行选择的结果:

var a1 = new Action(() => { /* if code block */ });
var a2 = new Action(() => { /* else code block */ });

Action resultingAction = test_variable ? a1 : a2;

resultingAction();

我通过执行相应的操作将其放在一个语句中。为了更简洁,我将第一个 lambda 表达式转换为 Action(而不是显式创建 new Action())并利用类型推断,我省略了第二个转换。

【讨论】:

  • 我喜欢它,避免指责 OP,而是让他有机会在未来接受 lambda 语法的教育。
  • 这个答案可能需要更多解释它的作用以及为什么它不是一个好主意。
  • 非常感谢您的回答,这实际上比我想象的要复杂。我只是想知道,因为我在几个地方看到了这些速记。但由于简单,我会坚持使用 if else 。出于兴趣,为什么第一个 lambda 有 Action 而第二个没有?请你解释一下?
  • @adminSoftDK:第一个、第二个或两个子表达式必须进行强制转换以避免编译器错误,“无法确定条件表达式的类型,因为 'lambda 表达式' 和 ' 之间没有隐式转换lambda 表达式'"。 Lambda 表达式没有可说的类型。另请参阅Why can't an anonymous method be assigned to var?
【解决方案2】:

没有。

三元运算符 (?:) 作为一个整体必须是一个表达式 - 即可以分配给某物的某物。

【讨论】:

  • 虽然条件运算符必须是有效的表达式是正确的,但不能使用这样的表达式来执行问题中描述的功能行为是不正确的。可以通过表达式创建行为,而不仅仅是语句。
  • @Servy : true,但是将此处的语句转换为表达式所需的操作将完全破坏使其成为“速记”的目标
  • 当然,如果你说这是可能的,只是没有比使用if 语句更方便,答案是正确的。当你说“不”时,可以证明答案是不正确的。
  • 您的回答暗示表达式的定义特征是它可以位于赋值的右侧。这不是表达式的定义。 c#中有11种东西可以作为表达式,而且大部分都不能出现在赋值的右边。
  • @EricLippert:虽然在技术上是正确的,但它是一种识别非语言设计师的开发人员使用的表达式类型的简单方法。即,虽然大多数人会知道 typeof int 是一个表达式(可以赋值),但很少有人会认识到这意味着操作数 int 也是一个表达式,尽管它不能赋值。但是,这种无知不太可能影响他的代码。
【解决方案3】:

假设你可以做到这一点。为什么?

动机是什么?

行数更少?不足以有所作为。 表现?没有,编译器会为你处理事情。 明晰? if/else 更清晰,更容易被大多数开发者理解。

我敢肯定,如果你足够努力,你可以找到一种方法来处理这个问题(很可能是一团糟),但我仍然无法确定原因。

【讨论】:

  • 动机是兴趣,如果没有,我仍然会坚持下去。但无论如何感谢您的评论:)
【解决方案4】:

条件运算符要求其第二个和第三个操作数是返回值的表达式(除了满足某些类型限制之外),而不是不解析为值的语句。您没有希望从当前执行的任一操作中返回的值。

您可以仅仅为了编译代码而返回一些无意义的值,但此时您添加的工作量比仅使用 if 多得多,if 是满足您要求的正确语义运算符,所以虽然这在技术上是可行的,但这不是一个好主意。

【讨论】:

  • 查看我对其他答案的评论,关于将值与表达式混为一谈。
【解决方案5】:
fullName = validName == true ? returnName(firstName)+" "+returnName(lastName) : validName == false ? invalidName("Invalid Name") : null


public string returnName(string name)
{
return name;
}

public string invalidName(string invalid)
{
MessageBox.Show(invalid);
return null;
}

正如其他人可能所说的那样,这是您可能并不想真正想做的事情,但是,这是可能的:P

【讨论】:

  • 这不是将相关的字符串文字分配给适当的名称变量。
  • 当然是。 OP 的代码是基于事先假设名称有效的假设来分配名称,然后在此之后立即分配值。显然,在此之前名称将是已知的,因此只需将它们传入并立即将它们连接到 fullName 中返回。与无效相同。
  • 他没有构造fullname 变量。他将值分配给两个单独的变量,namesurname。您没有分配任何一个这样的变量。
猜你喜欢
  • 2014-11-04
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 2013-08-18
  • 2011-06-02
  • 2012-04-09
  • 2013-01-05
  • 2016-12-25
相关资源
最近更新 更多