我们能不能简化这种单行程?

ora*_*rad 0 .net javascript c# lambda roslyn

我想知道我是否可以使用C#更像JavaScript来快捷代码.我尝试用更少的行来制作以下代码:

public async Task<bool> EnsureAuthenticated()
{
    if (!IsAuthenticated)
    {
        if (!(await Authenticate()).IsSuccess)
        {
            throw new AuthenticationException();
        };
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

哪个成了:

public async Task<bool> EnsureAuthenticated()
{
    Func<bool> throwException = () => { throw new AuthenticationException(); };
    return IsAuthenticated || (await Authenticate()).IsSuccess || throwException();
}
Run Code Online (Sandbox Code Playgroud)

我最接近单线的是:

public async Task<bool> EnsureAuthenticated()
{
    return IsAuthenticated || (await Authenticate()).IsSuccess ||
    ((Func<bool>)(() => { throw new AuthenticationException(); }))();
}
Run Code Online (Sandbox Code Playgroud)

与JavaScript中的等效代码相比,它仍然是太多代码(如果考虑async/await,则为EcmaScript 2017).但我的问题主要是关于lambda部分((Func<bool>)(() => { throw new AuthenticationException(); }))().

在C#或C#vNext中没有更简洁的方法吗?

JLR*_*she 5

首先,C#7 不会让你像你所描述的,通过允许使用的做一些事情throw在有条件的经营者的第2或第3操作数(?:).所以你可以像这样编写你的方法:

public async Task<bool> EnsureAuthenticated()
{
    return (IsAuthenticated || (await Authenticate()).IsSuccess)
        ? true
        : throw new AuthenticationException();
}
Run Code Online (Sandbox Code Playgroud)

但是,您似乎正在尝试将可读代码转换为相当于糟糕(几乎不可读)的JavaScript代码,并且由于强制将编码风格强加到C#中而增加了一些额外的不可读性.

你可以这样做; 它很简单:

public async Task<bool> EnsureAuthenticated()
{
    if (!IsAuthenticated && !(await Authenticate()).IsSuccess)
    {
        throw new AuthenticationException();
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用DeMorgan定律来消除其中一个!:

public async Task<bool> EnsureAuthenticated()
{
    if (!(IsAuthenticated || (await Authenticate()).IsSuccess))
    {
        throw new AuthenticationException();
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

但是当你想到它时,如果返回值只有一个可能的值,那么返回值就没那么明显了,所以你可以消除它.两个可能的结果然后变成(1)抛出或(2)不抛出而不是(1)抛出或(2)返回true:

public async Task EnsureAuthenticated()
{
    if (!(IsAuthenticated || (await Authenticate()).IsSuccess))
    {
        throw new AuthenticationException();
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,如果您决定使用返回的函数,true或者false不是抛出异常,那么它变得非常简单和简洁:

public async Task<bool> EnsureAuthenticated()
{
    return IsAuthenticated || (await Authenticate()).IsSuccess;
}
Run Code Online (Sandbox Code Playgroud)