我想知道我是否可以使用C#更像JavaScript来快捷代码。我尝试用更少的代码制作以下代码:
public async Task<bool> EnsureAuthenticated()
{
if (!IsAuthenticated)
{
if (!(await Authenticate()).IsSuccess)
{
throw new AuthenticationException();
};
}
return true;
}
哪个成了:
public async Task<bool> EnsureAuthenticated()
{
Func<bool> throwException = () => { throw new AuthenticationException(); };
return IsAuthenticated || (await Authenticate()).IsSuccess || throwException();
}
最接近单线的是:
public async Task<bool> EnsureAuthenticated()
{
return IsAuthenticated || (await Authenticate()).IsSuccess ||
((Func<bool>)(() => { throw new AuthenticationException(); }))();
}
与JavaScript中的等效代码相比,代码仍然太多(如果考虑async / await,则为EcmaScript 2017)。但我的问题主要是关于lambda部分((Func<bool>)(() => { throw new AuthenticationException(); }))()
。
在C#或C#vNext中有没有更简洁的方法呢?
答案 0 :(得分:5)
首先,C#7 允许您执行类似于您所描述的操作,允许在条件运算符的第2或第3个操作数中使用throw
({{1 }})。所以你可以这样编写你的方法:
?:
然而,看起来您正试图将可读代码转换为相当于糟糕(几乎不可读)的JavaScript代码,并且由于强制将编码风格强加到C#中而增加了一些额外的不可读性。
你可以这样做;它很简单:
public async Task<bool> EnsureAuthenticated()
{
return (IsAuthenticated || (await Authenticate()).IsSuccess)
? true
: throw new AuthenticationException();
}
您可以使用DeMorgan定律来消除其中一个public async Task<bool> EnsureAuthenticated()
{
if (!IsAuthenticated && !(await Authenticate()).IsSuccess)
{
throw new AuthenticationException();
}
return true;
}
s:
!
但是当你考虑它时,如果返回值只有一个可能的值,那么返回值就毫无意义,所以你可以消除它。然后两个可能的结果变成(1)抛出或(2)不抛出而不抛出(1)抛出或(2)返回public async Task<bool> EnsureAuthenticated()
{
if (!(IsAuthenticated || (await Authenticate()).IsSuccess))
{
throw new AuthenticationException();
}
return true;
}
:
true
当然,如果您决定使用返回public async Task EnsureAuthenticated()
{
if (!(IsAuthenticated || (await Authenticate()).IsSuccess))
{
throw new AuthenticationException();
}
}
或true
的函数而不是抛出异常,那么它会变得非常简单明了:
false