【问题标题】:A try-catch one liner (like "??" or ternary operator)try-catch one liner(如“??”或三元运算符)
【发布时间】:2015-05-23 14:00:49
【问题描述】:

所以我们有三元运算符。伟大的!然后是?? 运算符,它对nullable 变量进行合并。

例子:

string emptyIfNull = strValue ?? "";

问题:是否可以为 try-catch 实现这样的简单运算符?

例子:

string result = CoalesceException(someExpression, "");

public static T CoalesceException<T>(expression, defaultValue)
{
    try
    {
        return evaluate expression; // ?
    }
    catch
    {
        return defaultValue;
    }
}

是否有可能实现一种尽可能容易使用的方法,甚至是某种类似合并的运算符?

【问题讨论】:

  • 我不知道你为什么要这样做?您应该首先尝试捕获特定的异常,然后您也不应该使用 try catch 来确定程序流程
  • 例如,如果你遍历进程的MainModule,你会得到所有x64进程的异常。这就是这个“操作符”将发挥作用的地方。它用于内联异常处理,不需要有关异常(或冒泡)的特定信息。
  • 但是你掩盖了你遇到的一个问题,你知道你的程序有 x64 进程的问题,所以你应该尝试解决这些问题。如果发生了异常,那就是出了问题,应该花时间去处理,所以我认为没有什么捷径可走:)
  • 我不想讨论这个有用的具体例子,或者它是否有用。我只是在寻找一种适当的方法来实现这一点。
  • 你在 Swift 中有try? fooThatCanThrow ?? defaultValue,但在 C# 中还没有。至少,在 C# 8.0 中添加了可空性,因此有一天你会更短的语法。

标签: c# exception null-coalescing-operator


【解决方案1】:

你可以:

public static T CoalesceException<T>(Func<T> func, T defaultValue = default(T))
{
    try
    {
        return func();
    }
    catch
    {
        return defaultValue;
    }
}

但我不确定这是你想要的......

使用:

string emptyIfError = CoalesceException(() => someExpressionThatReturnsAString, "");

例如...

string shortString = null;

string emptyIfError = CoalesceException(() => shortString.Substring(10), "");

将返回 "" 而不是 NullReferenceException

重要

编写的函数将始终导致defaultValue 的“评估”。含义:

string Throws() { throw new Exception(); }

string str1 = somethingTrue == true ? "Foo" : Throws();

这里不会抛出异常,因为Throws() 不会被评估。 ?? 运算符也是如此。

string str2 = CoalesceException(() => ((string)null).ToString(), Throws());

在输入CoalesceException 之前引发异常。解决方案:

public static T CoalesceException<T>(Func<T> func, Func<T> defaultValue = null)
{
    try
    {
        return func();
    }
    catch
    {
        return defaultValue != null ? defaultValue() : default(T);
    }
}

用途:

string emptyIfError = CoalesceException(() => someExpressionThatReturnsAString, () => "");

【讨论】:

  • 现在简直太棒了! +1
  • 是的,我注意到了!谢谢:)
【解决方案2】:

这是我最后的一些东西,创建一个 One Liner TryCatch

用法

  var r = Task.TryCatch(() => _logic.Method01(param1, param2));

TryCatch 定义

public static class Task
{

    public static TResult TryCatch<TResult>(Func<TResult> methodDelegate)
    {
        try
        {
            return methodDelegate();
        }
        catch (Exception ex)
        {
            // .. exception handling ...
        }

        return default(TResult);
    }
}

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 1970-01-01
    • 2014-03-19
    • 2018-09-10
    • 2016-12-29
    相关资源
    最近更新 更多