How do I make a concrete type after using MakeGenericMethod in C#?












2















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);
}









share|improve this question

























  • 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











  • 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
















2















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);
}









share|improve this question

























  • 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











  • 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














2












2








2








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);
}









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 11:51







Chucky

















asked Nov 21 '18 at 11:13









ChuckyChucky

84842050




84842050













  • 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











  • 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



















  • 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











  • 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

















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












2 Answers
2






active

oldest

votes


















1














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 avoid NullReferenceException, because it is expected that there is exactly one value

  • Replaced as Task to direct cast, because it is expected to be Task






share|improve this answer
























  • 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











  • 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



















1














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.






share|improve this answer
























  • 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













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
});


}
});














draft saved

draft discarded


















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









1














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 avoid NullReferenceException, because it is expected that there is exactly one value

  • Replaced as Task to direct cast, because it is expected to be Task






share|improve this answer
























  • 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











  • 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
















1














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 avoid NullReferenceException, because it is expected that there is exactly one value

  • Replaced as Task to direct cast, because it is expected to be Task






share|improve this answer
























  • 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











  • 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














1












1








1







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 avoid NullReferenceException, because it is expected that there is exactly one value

  • Replaced as Task to direct cast, because it is expected to be Task






share|improve this answer













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 avoid NullReferenceException, because it is expected that there is exactly one value

  • Replaced as Task to direct cast, because it is expected to be Task







share|improve this answer












share|improve this answer



share|improve this answer










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 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











  • @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



















  • 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











  • 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

















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













1














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.






share|improve this answer
























  • 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


















1














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.






share|improve this answer
























  • 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
















1












1








1







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










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 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





















  • 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



















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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

Npm cannot find a required file even through it is in the searched directory