【问题标题】:Syntactic sugar for throwing with null coalesce operator使用空合并运算符抛出的语法糖
【发布时间】:2011-12-16 09:36:30
【问题描述】:

假设如果我们尝试将 null 分配给某个东西,我们想抛出,那么这个技巧呢:

public static class ExceptionExtension
    {
        public static T Throw<T>(this Exception exc)
        {
            throw exc;
        }
    }

我们可以像这样使用:

 return possibleNull  ?? new Exception("Unspecified something....").Throw<string>();

您认为这是一种好/最差/无用的做法吗?

【问题讨论】:

    标签: c# syntactic-sugar


    【解决方案1】:

    这对我来说毫无意义 - 不是很可读。我希望?? 运算符的第二个参数与possibleNull 的类型相同,而不是抛出异常。

    我更愿意看到:

    if(possibleNull == null)
    {
      throw new Exception("Unspecified something....");
    }
    
    return possibleNull;
    

    【讨论】:

    • 是的,这是一个技巧,对我来说似乎不错,但只是想要其他意见,谢谢! (+1) 在将您标记为回复之前,我会等待其他一些人。
    • @FelicePollano - 我明白了。当我编写代码时,有几件事我想牢记在心(因为其他人会阅读它)。 1.Principle of least astonishment。 2. 这句话:“始终编写代码,就好像最终维护代码的人将是一个知道你住在哪里的暴力精神病患者。”约翰·F·伍兹(John F. Woods)。
    【解决方案2】:

    创建某种抛出的静态帮助类可能会更好、更易读 像这样

    public static class ThrowHelper
    {
        public static TException ThrowIfNull<TException>(object value)
            where TException : Exception, new()
        {
            if (value == null) //or other checks
            {
              throw new TException();
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      你总是可以把它放在某种短名称的静态助手类中:

      public static class Never
      {
          public static T Null<T>(T value)
              where T : class
          {
              if (value == null) throw new ArgumentNullException();
              return value;
          }
      }
      
      myClass.AProperty = Never.Null(somePotentiallyNullValue);
      

      你的另一个例子没有多大意义,我会选择称之为“无用”的做法。

      为帮助类添加一点“流畅性”往往会专注于使内容更具可读性。

      http://en.wikipedia.org/wiki/Fluent_interface

      【讨论】:

      • 什么情况下无法编译?
      • @FelicePollano return val ?? throw new
      • 它可以编译,因为您可以将返回指定为泛型:不幸的是它无法推断。
      • @FelicePollano for return t ?? throw new ArgumentNullException(); 我收到编译器错误Invalid expression term 'throw'
      • @FelicePollano 啊,我没有注意到 OP 没有抛出异常,只是返回它,如果类型不兼容,这将不起作用。
      【解决方案4】:

      我认为这不是一个好习惯。

      首先,扩展方法本身只是为我们已经有关键字的东西引入了一个方法:throw。这可能会令人困惑。它声明了一个返回类型,尽管它永远不会返回一个值,只是为了在你想要使用它的上下文中取悦编译器。参考其他人已经指出的,这是一个“最惊讶的原则”。

      然后,看看您将如何使用此方法,生成的代码似乎不是很清晰可读。更糟糕的是:您只能在表达式中使用这种方法,因此您总是会得到以某种方式使用对象的代码(在您的示例中:只需返回它)并在同一行检查它是否为 null 作为副作用.我更喜欢明确地进行空检查,而不是与其他东西混合。像CuttingEdge.Conditions 这样的库可以帮助减少您为此输入的代码量。你会以这种方式在你的例子中使用它

      Condition.Requires(possibleNull , "possibleNull ").IsNotNull();
      return possibleNull; 
      

      【讨论】:

        猜你喜欢
        • 2019-10-19
        • 2012-04-12
        • 2013-09-13
        • 2014-04-10
        • 2016-04-08
        • 1970-01-01
        • 2012-09-19
        • 1970-01-01
        • 2010-12-19
        相关资源
        最近更新 更多