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中没有更简洁的方法吗?
首先,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)