I've written a lot of (await SomeTask).AsList();
in my project, and it's kind of annoying to keep wrapping it.
To fix this I've written a little extension method on Task<IEnumerable<T>>
to be able to do this for me.
The code is like this:
/// <summary>
/// Awaits the Task and returns the result as Task as List<T>.
/// </summary>
/// <typeparam name="T">The type of the list.</typeparam>
/// <param name="task">The task to await.</param>
/// <returns>A task which returns as List which can be awaited.</returns>
public static async Task<List<T>> AsListAsync<T>(this Task<IEnumerable<T>> task)
{
var result = await task;
return result.AsList();
}
public static List<T> AsList<T>(this IEnumerable<T> enumerable)
{
if (enumerable is List<T> list)
{
return list;
}
return new List<T>(enumerable);
}
This enables me to write this:
_someProperty = await SomeMethod().AsListAsync();
instead of:
_someProperty = (await SomeMethod()).AsList();
However I am not sure if this will introduce any unintended behavior or deadlocking. Can someone point out flaws in this code (if any)?
2 Answers 2
Just two points to mention
- you should add documentation to the second method as well, because it is a
public
method and you have documented the first method as well. - you should add a
null
check for the method parameters because one can call this methods directly as well, passingnull
.
I think you can implement the AsListAsync
as a one-liner
public static async Task<List<T>> AsListAsync<T>(this Task<IEnumerable<T>> task)
=> await task is List<T> list ? list : new List<T>(task.Result);
-
\$\begingroup\$ Yes this should work, however the AsList() method is used throughout the project, My goal wasn't to make the extension as compact as possible, but to be easy to read/understand. \$\endgroup\$Joost00719– Joost007192022年10月17日 09:18:40 +00:00Commented Oct 17, 2022 at 9:18
-
1\$\begingroup\$ @Joost00719 Is it hard to read/understand? Is it too concise? \$\endgroup\$Peter Csala– Peter Csala2022年10月17日 09:27:09 +00:00Commented Oct 17, 2022 at 9:27
-
\$\begingroup\$ No it's not very hard to understand, it's just a code style preference. I posted my code here to learn whether my code has any flaws, or if it's code which I can push to production without worrying about. \$\endgroup\$Joost00719– Joost007192022年10月17日 09:31:16 +00:00Commented Oct 17, 2022 at 9:31
-
1\$\begingroup\$ @Joost00719 I can only see two concerns 1) If the
IEnumerable
contains fairly large amount of data thenAsList
can be time consuming. 2) It might happen in the future that you have to supportIAsyncEnumerable
as well, whereAsList
might require you to do some external calls as well. \$\endgroup\$Peter Csala– Peter Csala2022年10月17日 09:56:19 +00:00Commented Oct 17, 2022 at 9:56 -
1\$\begingroup\$ @peter_Csla, thanks for the feedback! This wasn't something I thought of, and is good to know. Currently, I have no such case, so it isn't a problem for me (yet). I'll be putting a comment in the code that this is a possible issue if the dataset increases by a lot, or if the IEnumerable is IO bound. \$\endgroup\$Joost00719– Joost007192022年10月17日 10:11:43 +00:00Commented Oct 17, 2022 at 10:11
Explore related questions
See similar questions with these tags.
Task<IEnumerable<T>>
when you wantTask<List<T>>
? \$\endgroup\$