-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support csharp7 Generalized async return type alternative to TaskInterfaceFactory.Create #3
Comments
I have verified that generalized return types allow one to write code like this: [Test]
public async Task TaskInterfaceAsyncMethodBuilderTask()
{
await TaskInterfaceAsyncMethodBuilderTaskMethodAsync().ConfigureAwait(false);
}
async ITask TaskInterfaceAsyncMethodBuilderTaskMethodAsync()
{
await Task.Delay(50).ConfigureAwait(false);
}
[Test]
public async Task TaskInterfaceAsyncMethodBuilderResultTask()
{
var value = await TaskInterfaceAsyncMethodBuilderResultTaskMethodAsync().ConfigureAwait(false);
Assert.AreEqual(3, value);
}
async ITask<int> TaskInterfaceAsyncMethodBuilderResultTaskMethodAsync()
{
var results = await Task.WhenAll(
Enumerable.Range(0, 3).Select(async i =>
{
await Task.Delay(i);
return i;
}));
return results.Length;
} I’m about to submit a PR, but it is quite ugly because I don’t know how to use CodeContracts (and supposedly it doesn’t work with VS-2017/roslyn anyway because roslyn generated IL that is different from the old compilers, causing ccrewrite to fail to do things). Please review it and let me know if I can do things to make it work or if you can get the buildsystem to be compatible with VS-2017 and I can rebase my patches. |
Thanks for this! I have been meaning to look into this but I also was under the impression that interfaces were not supported. That's great to hear that they are! I will update AppVeyor to use Visual Studio 2017 to build. |
Also, I will remove the CodeContracts stuff. |
Awesome! Let me know when you're done and I can try to fix my commits/PR. I noticed I messed up the newlines of the README and I probably need to fix the .cs files to follow project newline conventions and license headers, etc. I'll fix that all after you make your changes. Alternatively, feel free to just copy and paste the implementation over—I don't care that much about commits being in my name ;-). |
Starting with csharp7 (regardless of targeted framework), supposedly any type can be used as a return type for an
async
method as the type is decorated with instructions to the compiler on how to build the type.https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7#generalized-async-return-types
It doesn’t really describe how to actually use generalized return types. And I haven’t actually tried it myself yet. Also, my only concern for this possibly not working is there’s a chance the compiler has some (unintentional, I think) inability to support
interface
(I only know of official examples forstruct
(ValueTask<TResult>
) andclass
(Task<TResult>
)), but that would probably be fixed by roslyn people if that is an issue. Below is what I think I understand so far how this works in csharp7:class System.Runtime.CompilerServices.AsyncMethodBuilderAttribute
internal to the assembly (the compiler just matches the assembly-local type name; this is purposeful to avoid requiring people to use the latest framework or reference external nugets).ITask<TResult>
similar toAsyncValueTaskMethodBuilder
.ITask<TResult>
in this case) with your attribute similar to howValueTuple<TResult>
is decorated.I suspect that the whole “method builder” might end up requiring implementation of some logic which wasn’t needed for
ITask<TResult>
.However, if this could be done, it would make implementing
ITask<TResult>
methods a ton cleaner. I think I am going to play with ITask and see if I can get a working implementation for it in my spare time.The text was updated successfully, but these errors were encountered: