How do I make a concrete type after using MakeGenericMethod in C#?
A bit of background, I'm working with some code someone else wrote. It's a REST API that you can issue queries and commands to and they are handled in a generic fashion.
The method for resolving queries is like so:
[HttpPost]
[Route("query")]
public async Task<Task> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).FirstOrDefault();
var responseType = interfaceType.GetGenericArguments()[0];
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = handleMethod.Invoke(this.bus, new object { query }) as Task;
await task;
return task;
}
I'm pretty sure it's very unusual to be using tasks in this way.
So when the handleMethod is invoked, even though it's result is being cast as a Task, and I can see a valid result when I mouse over it during debugging, there is no task.Result
member for me to use for eventual casting.
Things I've tried:
I've tried casting this handleMethod.Invoke as the 'resopnseType' I need, using Convert.ChangeType(result, responseType);
but I get an exception for not implementing IConvertible. Do I really have to implement IConvertible for every type that I need returned?
I've also tried having the return type set to Task, but I then need to specify TResponse in ResolveQuery and this gets an internal server error (I'm not sure how I specify the TResponse from my calling code).
I've also tried asking the programmer what he was doing here. He does not know. He was following another programmer's original advice for this implementation, but that programmer isn't here at present, otherwise I'd be asking him!
Can anyone tell me how to correctly get my result from the task object and return it, in a RESTful manner, to the calling client?
Update - in response to @Yeldar Kurmangaliyev
public interface IQueryBus
{
Task<TResponse> ResolveAsync<TResponse>(IQuery<TResponse> query);
}
c# rest generics casting task
add a comment |
A bit of background, I'm working with some code someone else wrote. It's a REST API that you can issue queries and commands to and they are handled in a generic fashion.
The method for resolving queries is like so:
[HttpPost]
[Route("query")]
public async Task<Task> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).FirstOrDefault();
var responseType = interfaceType.GetGenericArguments()[0];
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = handleMethod.Invoke(this.bus, new object { query }) as Task;
await task;
return task;
}
I'm pretty sure it's very unusual to be using tasks in this way.
So when the handleMethod is invoked, even though it's result is being cast as a Task, and I can see a valid result when I mouse over it during debugging, there is no task.Result
member for me to use for eventual casting.
Things I've tried:
I've tried casting this handleMethod.Invoke as the 'resopnseType' I need, using Convert.ChangeType(result, responseType);
but I get an exception for not implementing IConvertible. Do I really have to implement IConvertible for every type that I need returned?
I've also tried having the return type set to Task, but I then need to specify TResponse in ResolveQuery and this gets an internal server error (I'm not sure how I specify the TResponse from my calling code).
I've also tried asking the programmer what he was doing here. He does not know. He was following another programmer's original advice for this implementation, but that programmer isn't here at present, otherwise I'd be asking him!
Can anyone tell me how to correctly get my result from the task object and return it, in a RESTful manner, to the calling client?
Update - in response to @Yeldar Kurmangaliyev
public interface IQueryBus
{
Task<TResponse> ResolveAsync<TResponse>(IQuery<TResponse> query);
}
c# rest generics casting task
There is noResult
, because it is just aTask
. You need to cast it to specificTask<T>
or use reflection once again to get result. Show the code of yourIQueryBus
interface.
– Yeldar Kurmangaliyev
Nov 21 '18 at 11:18
How can I pass in the T needed in Task<T> for casting?
– Chucky
Nov 21 '18 at 11:36
Could you please shareIQueryBus
code?
– Yeldar Kurmangaliyev
Nov 21 '18 at 11:48
Sorry, I misread you earlier, one moment
– Chucky
Nov 21 '18 at 11:50
add a comment |
A bit of background, I'm working with some code someone else wrote. It's a REST API that you can issue queries and commands to and they are handled in a generic fashion.
The method for resolving queries is like so:
[HttpPost]
[Route("query")]
public async Task<Task> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).FirstOrDefault();
var responseType = interfaceType.GetGenericArguments()[0];
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = handleMethod.Invoke(this.bus, new object { query }) as Task;
await task;
return task;
}
I'm pretty sure it's very unusual to be using tasks in this way.
So when the handleMethod is invoked, even though it's result is being cast as a Task, and I can see a valid result when I mouse over it during debugging, there is no task.Result
member for me to use for eventual casting.
Things I've tried:
I've tried casting this handleMethod.Invoke as the 'resopnseType' I need, using Convert.ChangeType(result, responseType);
but I get an exception for not implementing IConvertible. Do I really have to implement IConvertible for every type that I need returned?
I've also tried having the return type set to Task, but I then need to specify TResponse in ResolveQuery and this gets an internal server error (I'm not sure how I specify the TResponse from my calling code).
I've also tried asking the programmer what he was doing here. He does not know. He was following another programmer's original advice for this implementation, but that programmer isn't here at present, otherwise I'd be asking him!
Can anyone tell me how to correctly get my result from the task object and return it, in a RESTful manner, to the calling client?
Update - in response to @Yeldar Kurmangaliyev
public interface IQueryBus
{
Task<TResponse> ResolveAsync<TResponse>(IQuery<TResponse> query);
}
c# rest generics casting task
A bit of background, I'm working with some code someone else wrote. It's a REST API that you can issue queries and commands to and they are handled in a generic fashion.
The method for resolving queries is like so:
[HttpPost]
[Route("query")]
public async Task<Task> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).FirstOrDefault();
var responseType = interfaceType.GetGenericArguments()[0];
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = handleMethod.Invoke(this.bus, new object { query }) as Task;
await task;
return task;
}
I'm pretty sure it's very unusual to be using tasks in this way.
So when the handleMethod is invoked, even though it's result is being cast as a Task, and I can see a valid result when I mouse over it during debugging, there is no task.Result
member for me to use for eventual casting.
Things I've tried:
I've tried casting this handleMethod.Invoke as the 'resopnseType' I need, using Convert.ChangeType(result, responseType);
but I get an exception for not implementing IConvertible. Do I really have to implement IConvertible for every type that I need returned?
I've also tried having the return type set to Task, but I then need to specify TResponse in ResolveQuery and this gets an internal server error (I'm not sure how I specify the TResponse from my calling code).
I've also tried asking the programmer what he was doing here. He does not know. He was following another programmer's original advice for this implementation, but that programmer isn't here at present, otherwise I'd be asking him!
Can anyone tell me how to correctly get my result from the task object and return it, in a RESTful manner, to the calling client?
Update - in response to @Yeldar Kurmangaliyev
public interface IQueryBus
{
Task<TResponse> ResolveAsync<TResponse>(IQuery<TResponse> query);
}
c# rest generics casting task
c# rest generics casting task
edited Nov 21 '18 at 11:51
Chucky
asked Nov 21 '18 at 11:13


ChuckyChucky
84842050
84842050
There is noResult
, because it is just aTask
. You need to cast it to specificTask<T>
or use reflection once again to get result. Show the code of yourIQueryBus
interface.
– Yeldar Kurmangaliyev
Nov 21 '18 at 11:18
How can I pass in the T needed in Task<T> for casting?
– Chucky
Nov 21 '18 at 11:36
Could you please shareIQueryBus
code?
– Yeldar Kurmangaliyev
Nov 21 '18 at 11:48
Sorry, I misread you earlier, one moment
– Chucky
Nov 21 '18 at 11:50
add a comment |
There is noResult
, because it is just aTask
. You need to cast it to specificTask<T>
or use reflection once again to get result. Show the code of yourIQueryBus
interface.
– Yeldar Kurmangaliyev
Nov 21 '18 at 11:18
How can I pass in the T needed in Task<T> for casting?
– Chucky
Nov 21 '18 at 11:36
Could you please shareIQueryBus
code?
– Yeldar Kurmangaliyev
Nov 21 '18 at 11:48
Sorry, I misread you earlier, one moment
– Chucky
Nov 21 '18 at 11:50
There is no
Result
, because it is just a Task
. You need to cast it to specific Task<T>
or use reflection once again to get result. Show the code of your IQueryBus
interface.– Yeldar Kurmangaliyev
Nov 21 '18 at 11:18
There is no
Result
, because it is just a Task
. You need to cast it to specific Task<T>
or use reflection once again to get result. Show the code of your IQueryBus
interface.– Yeldar Kurmangaliyev
Nov 21 '18 at 11:18
How can I pass in the T needed in Task<T> for casting?
– Chucky
Nov 21 '18 at 11:36
How can I pass in the T needed in Task<T> for casting?
– Chucky
Nov 21 '18 at 11:36
Could you please share
IQueryBus
code?– Yeldar Kurmangaliyev
Nov 21 '18 at 11:48
Could you please share
IQueryBus
code?– Yeldar Kurmangaliyev
Nov 21 '18 at 11:48
Sorry, I misread you earlier, one moment
– Chucky
Nov 21 '18 at 11:50
Sorry, I misread you earlier, one moment
– Chucky
Nov 21 '18 at 11:50
add a comment |
2 Answers
2
active
oldest
votes
There is no Result
, because it is just a non-generic Task
.
In order to get result you need a Task<T>
. Since you don't know T
in design-time, you need to use reflection again:
public async Task<object> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).Single();
var responseType = interfaceType.GetGenericArguments().Single();
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = (Task)handleMethod.Invoke(this.bus, new object { query });
await task;
return typeof(Task<>).MakeGenericType(responseType).GetProperty("Result").GetValue(task);
}
It will create a Result
property for your specific Task<responseType>
and return its value.
I have slightly updated the existing code too, just as a suggestion:
- Changed
[0]
and.FirstOrDefault()
to.Single()
to avoidNullReferenceException
, because it is expected that there is exactly one value - Replaced
as Task
to direct cast, because it is expected to beTask
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
@Chucky Yes,task
is of typeTask
, but actually it isTask<TResult>
whereTResult
is unknown in design time, and you dynamically access itsTask<TResult>.Result
property.
– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
Superb! I'm unfamiliar with the syntaxTask<>
. I take it this just means you don't have to specific the type?
– Chucky
Nov 21 '18 at 13:58
@ChuckyTask
is the base class, it contains all the logic of tasks, but has noResult
. Basically, it is an asynchronous equivalent ofvoid
. So, there is no result returned fromvoid
.Task<TResult>
is inherited fromTask
and represents asynchronous method which returnsTResult
.Task<T>
has additional property namedResult
of typeT
, so this is what you need through reflection if you want to get the result of a task.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
add a comment |
I have encountered that very same problem few weeks ago. Unfortunately I can't find the page where I read that sacred sentence but here it is:
"Awaiting generic methods through reflection is only possible with cast to dynamic
which resolves in Task< target type>"
So to give you an example how it should look in your case:
dynamic taskResult = await (dynamic)handleMethod.Invoke(this.bus, new object { query });
Yes, dynamic is not the best thing but helps in such scenarios where the compiler has no idea of what type would the generic T parameter.
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
General recommendation is not to usedynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not usedynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53410891%2fhow-do-i-make-a-concrete-type-after-using-makegenericmethod-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
There is no Result
, because it is just a non-generic Task
.
In order to get result you need a Task<T>
. Since you don't know T
in design-time, you need to use reflection again:
public async Task<object> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).Single();
var responseType = interfaceType.GetGenericArguments().Single();
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = (Task)handleMethod.Invoke(this.bus, new object { query });
await task;
return typeof(Task<>).MakeGenericType(responseType).GetProperty("Result").GetValue(task);
}
It will create a Result
property for your specific Task<responseType>
and return its value.
I have slightly updated the existing code too, just as a suggestion:
- Changed
[0]
and.FirstOrDefault()
to.Single()
to avoidNullReferenceException
, because it is expected that there is exactly one value - Replaced
as Task
to direct cast, because it is expected to beTask
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
@Chucky Yes,task
is of typeTask
, but actually it isTask<TResult>
whereTResult
is unknown in design time, and you dynamically access itsTask<TResult>.Result
property.
– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
Superb! I'm unfamiliar with the syntaxTask<>
. I take it this just means you don't have to specific the type?
– Chucky
Nov 21 '18 at 13:58
@ChuckyTask
is the base class, it contains all the logic of tasks, but has noResult
. Basically, it is an asynchronous equivalent ofvoid
. So, there is no result returned fromvoid
.Task<TResult>
is inherited fromTask
and represents asynchronous method which returnsTResult
.Task<T>
has additional property namedResult
of typeT
, so this is what you need through reflection if you want to get the result of a task.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
add a comment |
There is no Result
, because it is just a non-generic Task
.
In order to get result you need a Task<T>
. Since you don't know T
in design-time, you need to use reflection again:
public async Task<object> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).Single();
var responseType = interfaceType.GetGenericArguments().Single();
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = (Task)handleMethod.Invoke(this.bus, new object { query });
await task;
return typeof(Task<>).MakeGenericType(responseType).GetProperty("Result").GetValue(task);
}
It will create a Result
property for your specific Task<responseType>
and return its value.
I have slightly updated the existing code too, just as a suggestion:
- Changed
[0]
and.FirstOrDefault()
to.Single()
to avoidNullReferenceException
, because it is expected that there is exactly one value - Replaced
as Task
to direct cast, because it is expected to beTask
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
@Chucky Yes,task
is of typeTask
, but actually it isTask<TResult>
whereTResult
is unknown in design time, and you dynamically access itsTask<TResult>.Result
property.
– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
Superb! I'm unfamiliar with the syntaxTask<>
. I take it this just means you don't have to specific the type?
– Chucky
Nov 21 '18 at 13:58
@ChuckyTask
is the base class, it contains all the logic of tasks, but has noResult
. Basically, it is an asynchronous equivalent ofvoid
. So, there is no result returned fromvoid
.Task<TResult>
is inherited fromTask
and represents asynchronous method which returnsTResult
.Task<T>
has additional property namedResult
of typeT
, so this is what you need through reflection if you want to get the result of a task.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
add a comment |
There is no Result
, because it is just a non-generic Task
.
In order to get result you need a Task<T>
. Since you don't know T
in design-time, you need to use reflection again:
public async Task<object> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).Single();
var responseType = interfaceType.GetGenericArguments().Single();
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = (Task)handleMethod.Invoke(this.bus, new object { query });
await task;
return typeof(Task<>).MakeGenericType(responseType).GetProperty("Result").GetValue(task);
}
It will create a Result
property for your specific Task<responseType>
and return its value.
I have slightly updated the existing code too, just as a suggestion:
- Changed
[0]
and.FirstOrDefault()
to.Single()
to avoidNullReferenceException
, because it is expected that there is exactly one value - Replaced
as Task
to direct cast, because it is expected to beTask
There is no Result
, because it is just a non-generic Task
.
In order to get result you need a Task<T>
. Since you don't know T
in design-time, you need to use reflection again:
public async Task<object> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).Single();
var responseType = interfaceType.GetGenericArguments().Single();
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = (Task)handleMethod.Invoke(this.bus, new object { query });
await task;
return typeof(Task<>).MakeGenericType(responseType).GetProperty("Result").GetValue(task);
}
It will create a Result
property for your specific Task<responseType>
and return its value.
I have slightly updated the existing code too, just as a suggestion:
- Changed
[0]
and.FirstOrDefault()
to.Single()
to avoidNullReferenceException
, because it is expected that there is exactly one value - Replaced
as Task
to direct cast, because it is expected to beTask
answered Nov 21 '18 at 12:07


Yeldar KurmangaliyevYeldar Kurmangaliyev
24.9k93966
24.9k93966
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
@Chucky Yes,task
is of typeTask
, but actually it isTask<TResult>
whereTResult
is unknown in design time, and you dynamically access itsTask<TResult>.Result
property.
– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
Superb! I'm unfamiliar with the syntaxTask<>
. I take it this just means you don't have to specific the type?
– Chucky
Nov 21 '18 at 13:58
@ChuckyTask
is the base class, it contains all the logic of tasks, but has noResult
. Basically, it is an asynchronous equivalent ofvoid
. So, there is no result returned fromvoid
.Task<TResult>
is inherited fromTask
and represents asynchronous method which returnsTResult
.Task<T>
has additional property namedResult
of typeT
, so this is what you need through reflection if you want to get the result of a task.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
add a comment |
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
@Chucky Yes,task
is of typeTask
, but actually it isTask<TResult>
whereTResult
is unknown in design time, and you dynamically access itsTask<TResult>.Result
property.
– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
Superb! I'm unfamiliar with the syntaxTask<>
. I take it this just means you don't have to specific the type?
– Chucky
Nov 21 '18 at 13:58
@ChuckyTask
is the base class, it contains all the logic of tasks, but has noResult
. Basically, it is an asynchronous equivalent ofvoid
. So, there is no result returned fromvoid
.Task<TResult>
is inherited fromTask
and represents asynchronous method which returnsTResult
.Task<T>
has additional property namedResult
of typeT
, so this is what you need through reflection if you want to get the result of a task.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
So even though I cast it as a Task (i.e. returning void) it can have a Result?
– Chucky
Nov 21 '18 at 12:21
@Chucky Yes,
task
is of type Task
, but actually it is Task<TResult>
where TResult
is unknown in design time, and you dynamically access its Task<TResult>.Result
property.– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
@Chucky Yes,
task
is of type Task
, but actually it is Task<TResult>
where TResult
is unknown in design time, and you dynamically access its Task<TResult>.Result
property.– Yeldar Kurmangaliyev
Nov 21 '18 at 13:49
Superb! I'm unfamiliar with the syntax
Task<>
. I take it this just means you don't have to specific the type?– Chucky
Nov 21 '18 at 13:58
Superb! I'm unfamiliar with the syntax
Task<>
. I take it this just means you don't have to specific the type?– Chucky
Nov 21 '18 at 13:58
@Chucky
Task
is the base class, it contains all the logic of tasks, but has no Result
. Basically, it is an asynchronous equivalent of void
. So, there is no result returned from void
. Task<TResult>
is inherited from Task
and represents asynchronous method which returns TResult
. Task<T>
has additional property named Result
of type T
, so this is what you need through reflection if you want to get the result of a task.– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
@Chucky
Task
is the base class, it contains all the logic of tasks, but has no Result
. Basically, it is an asynchronous equivalent of void
. So, there is no result returned from void
. Task<TResult>
is inherited from Task
and represents asynchronous method which returns TResult
. Task<T>
has additional property named Result
of type T
, so this is what you need through reflection if you want to get the result of a task.– Yeldar Kurmangaliyev
Nov 21 '18 at 14:19
add a comment |
I have encountered that very same problem few weeks ago. Unfortunately I can't find the page where I read that sacred sentence but here it is:
"Awaiting generic methods through reflection is only possible with cast to dynamic
which resolves in Task< target type>"
So to give you an example how it should look in your case:
dynamic taskResult = await (dynamic)handleMethod.Invoke(this.bus, new object { query });
Yes, dynamic is not the best thing but helps in such scenarios where the compiler has no idea of what type would the generic T parameter.
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
General recommendation is not to usedynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not usedynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
add a comment |
I have encountered that very same problem few weeks ago. Unfortunately I can't find the page where I read that sacred sentence but here it is:
"Awaiting generic methods through reflection is only possible with cast to dynamic
which resolves in Task< target type>"
So to give you an example how it should look in your case:
dynamic taskResult = await (dynamic)handleMethod.Invoke(this.bus, new object { query });
Yes, dynamic is not the best thing but helps in such scenarios where the compiler has no idea of what type would the generic T parameter.
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
General recommendation is not to usedynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not usedynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
add a comment |
I have encountered that very same problem few weeks ago. Unfortunately I can't find the page where I read that sacred sentence but here it is:
"Awaiting generic methods through reflection is only possible with cast to dynamic
which resolves in Task< target type>"
So to give you an example how it should look in your case:
dynamic taskResult = await (dynamic)handleMethod.Invoke(this.bus, new object { query });
Yes, dynamic is not the best thing but helps in such scenarios where the compiler has no idea of what type would the generic T parameter.
I have encountered that very same problem few weeks ago. Unfortunately I can't find the page where I read that sacred sentence but here it is:
"Awaiting generic methods through reflection is only possible with cast to dynamic
which resolves in Task< target type>"
So to give you an example how it should look in your case:
dynamic taskResult = await (dynamic)handleMethod.Invoke(this.bus, new object { query });
Yes, dynamic is not the best thing but helps in such scenarios where the compiler has no idea of what type would the generic T parameter.
answered Nov 21 '18 at 12:10
Kia KahaKia Kaha
112
112
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
General recommendation is not to usedynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not usedynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
add a comment |
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
General recommendation is not to usedynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not usedynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.
– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
this answer and Yeldar's both work for me. I'm unsure which is better so I'm going to upvote both and maybe wait for more discussion before marking either as correct.
– Chucky
Nov 21 '18 at 14:02
General recommendation is not to use
dynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not use dynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
General recommendation is not to use
dynamic
unless you have to. Your case can be considered to be "you have to", because it is more readable than reflection, and approximately as bad in terms of performance. Personally I would not use dynamic
, because I never use it in my code, but it is arguable and mostly a matter of taste and team coding style preferences.– Yeldar Kurmangaliyev
Nov 21 '18 at 14:17
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53410891%2fhow-do-i-make-a-concrete-type-after-using-makegenericmethod-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
There is no
Result
, because it is just aTask
. You need to cast it to specificTask<T>
or use reflection once again to get result. Show the code of yourIQueryBus
interface.– Yeldar Kurmangaliyev
Nov 21 '18 at 11:18
How can I pass in the T needed in Task<T> for casting?
– Chucky
Nov 21 '18 at 11:36
Could you please share
IQueryBus
code?– Yeldar Kurmangaliyev
Nov 21 '18 at 11:48
Sorry, I misread you earlier, one moment
– Chucky
Nov 21 '18 at 11:50