This is NOT a failure of anything. I'm just trying to determine how to write c# more elegantly.
In a C# project I find I am doing an awful lot of
if (null != classX.user || await classX.getUserAsync())
{
// getUserAsync() either sets classX.user appropriately and returns true, or else returns false.
// Calls to classX members and other functions that are only OK when classX.user is valid follow
and I'd like to bundle this into a member function like
private async Task<bool> IsUserSet()
{
if (null != user)
return await Task.FromResult<bool>(user);
return await getUserAsync();
}
because (IMHO) replacing the if statement with if (IsUserSet())
is more readable.
However, I'm wondering if the performance hit (there is one with inserting another Task isn't there?) is worth it, or if there is a way to do this without inserting another task. (Or maybe I just need some education on how to write cleaner ASP.NET code!)
*** FINAL Edit after learning a lot from all the comments:
ValueTask
for any intermediate Task functions
(or when appropriate), it can reduce overhead (thanks Charlieface).Task.FromResult<>
(I don't
know where I picked up that habit) it adds unnecessary overhead (phuzi).I think you were nearly there with
private async Task<bool> IsUserSet()
{
if (null != user)
return await Task.FromResult<bool>(user);
return await getUserAsync();
}
but return await Task.FromResult<bool>(user);
would need to be return true;
You could simplify this and do something similar to your original code.
private async Task<bool> IsUserSet()
{
return user is not null || await getUserAsync();
}
await Task.FromResult()
When you do await Task.FromResult<bool>(user)
you have redundant code.
Task.FromResult<bool>(user)
wraps user
in a completed task and prefixing it with await
automatically unwraps it, so await Task.FromResult<bool>(user)
can be reduced to user
as you weren't actually returning Task<bool>
but bool
all along and marking a method as async
automatically wraps the returned value in a task`