是否有效:C#多个三元运算符+如果不匹配则抛出

use*_*035 34 c# coding-style exception conditional-operator

您是否发现以下C#代码清晰可辨?

private bool CanExecuteAdd(string parameter) {
    return
        this.Script == null ? false
        : parameter == "Step" ? true
        : parameter == "Element" ? this.ElementSelectedInLibrary != null && this.SelectedStep != null
        : parameter == "Choice" ? this.SelectedElement != null
        : parameter == "Jump" ? this.SelectedStep != null
        : parameter == "Conditional jump" ? false
        : false.Throw("Unknown Add parameter {0} in XAML.".F(parameter));
}
Run Code Online (Sandbox Code Playgroud)

其中Throw定义为:

public static T Throw<T>(this T ignored, string message) {
    throw new Exception(message);
}
Run Code Online (Sandbox Code Playgroud)

我知道这不是惯用的C#.但是,你能在第一眼还是第二眼看到它?还是我偏离了太远?

Fed*_*ede 29

为什么不使用开关?我认为它更具可读性.

private bool CanExecuteAdd(string parameter) {
    if (Script == null)
        return false;

    switch (parameter) {
        case "Step":
            return true;
        case "Element":
            return ElementSelectedInLibrary != null && SelectedStep != null;
        case "Choice":
            return SelectedElement != null;
        case "Jump":
            return SelectedStep != null;
        case "Conditional jump":
            return false;
        default:
            throw new Exception(string.Format("Unknown Add parameter {0} in XAML.", parameter));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢使用合适的工具来做正确的工作.IMO switch语句是此特定方案的最佳解决方案.在另一种情况下,我肯定会考虑使用@John Weldon建议的命令模式 (2认同)

Jon*_*eet 27

我已经在Java中使用了这种代码.我不喜欢这个false.Throw,但是在我看来,有这样的多个条件(特别是这样格式化)很好.

这是你第一次看到它时有点奇怪,但在那之后它只是一个方便的模式来了解.

false.Throw在这里使用的一种替代方案是这样的:

bool? ret = this.Script == null ? false
    : parameter == "Step" ? true
    : parameter == "Element" ? this.ElementSelectedInLibrary != null && this.SelectedStep != null
    : parameter == "Choice" ? this.SelectedElement != null
    : parameter == "Jump" ? this.SelectedStep != null
    : parameter == "Conditional jump" ? false
    : null;

if (ret == null)
{
    throw new ArgumentException(
       string.Format("Unknown Add parameter {0} in XAML.", parameter);
}
return ret.Value;
Run Code Online (Sandbox Code Playgroud)

编辑:实际上,在这种情况下,我不会使用if/else 这种模式...我会使用开关/案例.如果您需要,这可以非常紧凑:

if (this.Script == null)
{
    return false;
}
switch (parameter)
{
    case "Step": return true;
    case "Element": return this.ElementSelectedInLibrary != null && this.SelectedStep != null;
    case "Choice": return this.SelectedElement != null;
    case "Jump": return this.SelectedStep != null;
    default: throw new ArgumentException(
        string.Format("Unknown Add parameter {0} in XAML.", parameter);
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 10

我的经验法则:对没有副作用的东西使用表达式.对具有单一效果和控制流的事物使用语句.

投掷实际上是副作用; 它不计算值,它会改变控制流量.您正在计算价值,计算,计算,计算,然后繁荣,副作用.我发现这样的代码令人困惑和烦恼.我说控制流应该在语句中,而不是看起来像计算的东西的副作用.

  • @wwosik:你提出了一个很好的观点.如果某事实际上是*不可能*那么它不应该是例外; 例外应该是可测试的.这应该是一个断言. (2认同)

KP.*_*KP. 8

我投票支持不清晰.

虽然语法是正确的,但它有点令人费解,因为它不是,我敢说,"传统",许多开发人员将不得不浪费时间来确保他们理解他们正在阅读的东西.不是一个理想的情况.

可读性绝对是良好编码的关键因素,我想说大多数开发人员都不会立即阅读您的样本.

  • @wwosik:奇怪几乎总是坏的.这是一种分散注意力并引起读者注意力的消耗.既然你似乎关心你的代码的读者,你应该关心他们的时间. (3认同)

Joh*_*don 6

我喜欢条件运算符,并且使用它很多.

这个例子有点令人困惑,因为操作员的性质在布局和用法上并不清楚.

至少我喜欢通过使用这种格式来做出选择和替代方案:

choice
  ? true-case
  : false-case
Run Code Online (Sandbox Code Playgroud)

但是,如果我们将其应用于您的代码,则表明以这种方式使用构造时缺乏明确性:

return
    this.Script == null 
                ? false 
                : parameter == "Step" 
                    ? true
                    : parameter == "Element" 
                        ? this.ElementSelectedInLibrary != null && this.SelectedStep != null
                        : parameter == "Choice" 
                            ? this.SelectedElement != null
                            : parameter == "Jump" 
                                ? this.SelectedStep != null
                                : parameter == "Conditional jump" 
                                        ? false
                                        : false.Throw("Unknown Add parameter {0} in XAML.".F(parameter));
Run Code Online (Sandbox Code Playgroud)

这对我来说就像我们试图像switch语句那样使用条件运算符,其中switch语句或者更好的设计模式(如命令模式)会更加清晰.

  • 好吧,有了您的格式,我将永远不会使用该构造。整个问题在于?和: (2认同)

Dav*_*ton 5

我真的不喜欢这段代码.我花了大约15秒才明白,所以我放弃了.

if/then会更好.