-
Sometimes when working with reflection and generic types it would have been nice to be able to do something like this //Some code to find the method info
Task<ANY> res = mi.Invoke(....); //Assuming that we know that mi is a MethodInfo witch returnParameter.Type is some kind of Task<>
await res;
return res.Result; // The Result will be of type object at coding time. This can be solved today by finding the generic type parameter and, and use the |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
Effectively, what you're asking for is to make // Some code to find the method info
// Assuming that we know that mi is a MethodInfo whose returnParameter.Type is
// some kind of Task<T>, where T is a reference type
var res = (ITask<object>)mi.Invoke(....);
return await res; Though if you look at the state of the two issues I linked to, it doesn't seem like this is going to happen any time soon. |
Beta Was this translation helpful? Give feedback.
-
Thank you @svick nice explanation 😄 |
Beta Was this translation helpful? Give feedback.
-
Related to my proposal which would allow you to bring the runtime type argument into the scope and use it freely like a generic parameter. |
Beta Was this translation helpful? Give feedback.
-
This is actually nothing to do with variance, what your trying to express here is an existential type which while a bit clunky can be expressed with the current type system. Example C# fiddle here: https://dotnetfiddle.net/1qO0au It's a lot easier with F# because that has object expressions, there's a blog post all about this idea in F# from G-Research https://www.gresearch.co.uk/article/squeezing-more-out-of-the-f-type-system-introducing-crates/ Having some way to express quantified types (that is existential or universal) would be nice, but I imagine it would only get traction if either: This also relates to HKT (#339) because currently you have to write new classes for every type you want to "crate up". So you end up with a ListCrate, TaskCrate, ArrayCrate, etc. While if you had HKT you could do something like: public abstract class CrateEvaluator<M<T>, U>
{
public abstract U Eval<T>(M<T> obj);
}
public abstract class Crate<M<T>>
{
public abstract U Apply<U>(CrateEvaluator<M, U> evaluator);
}
public sealed class Crate<M<T>, T> : Crate<M>
{
readonly M<T> _obj;
public Crate(M<T> obj)
{
_obj = obj;
}
public override U Apply<U>(CrateEvaluator<M, U> evaluator)
{
return evaluator.Eval<T>(_obj);
}
} Three types that would cover every crate where your hiding just one type parameter. Instead of ListCrate, ArrayCrate you'd pass around |
Beta Was this translation helpful? Give feedback.
-
@petterek , this is achievable via third-party library if you need the solution right now. Here is the documentation. //assume that t is of unknown Task<T> type
Task t = Task.FromResult("Hello, world!");
object result = await t.AsDynamic(); |
Beta Was this translation helpful? Give feedback.
-
Thanks, for that, I solved it by using reflection and the "createGenericType" method. |
Beta Was this translation helpful? Give feedback.
Effectively, what you're asking for is to make
Task<T>
covariant (dotnet/roslyn#2981). But classes can't be covariant in .Net, only interfaces can. Which means it would be possible to add an interfaceITask<T>
(dotnet/runtime#20016), which would allow you to write:Though if you look at the state of the two issues I linked to, it doesn't seem like this is going to happen any time soon.