Click here to Skip to main content
15,890,123 members
Home / Discussions / C#
   

C#

 
GeneralRe: Cannot convert from system...IList to class[] Pin
Sevententh5-Oct-09 23:27
Sevententh5-Oct-09 23:27 
QuestionOdd behaviour when selecting item in a Combobox [Fixed it, my fault] Pin
Anthony Mushrow2-Oct-09 4:07
professionalAnthony Mushrow2-Oct-09 4:07 
QuestionC# TCP networkstreem problem Pin
Titok Levi2-Oct-09 2:32
Titok Levi2-Oct-09 2:32 
AnswerRe: C# TCP networkstreem problem Pin
Luc Pattyn2-Oct-09 3:06
sitebuilderLuc Pattyn2-Oct-09 3:06 
AnswerRe: C# TCP networkstreem problem Pin
0x3c02-Oct-09 3:56
0x3c02-Oct-09 3:56 
AnswerRe: C# TCP networkstreem problem Pin
Tr@v2-Oct-09 16:26
Tr@v2-Oct-09 16:26 
GeneralRe: C# TCP networkstreem problem Pin
Titok Levi6-Oct-09 22:03
Titok Levi6-Oct-09 22:03 
QuestionGenerics, delegates and type inference Pin
dojohansen2-Oct-09 2:10
dojohansen2-Oct-09 2:10 
Hi all,

I'm trying to use a web service with authenticated access. The service returns a session token with every response and the token may change during the session. Operations on the service all follow a simple pattern: They take one argument representing the request, and return an object representing the response. Each operation has a specific req/response associated with it, but requests are derived from a common base class and responses from another. The base classes provide access to the headers, so they are sufficient to manage the session.

The business object I'm writing that uses the service will execute code in multiple threads. Rather than duplicate the thread-synchronization and token-maintenance code everywhere I invoke a service operation, I thought I'd use generics and delegates so the generic method would implement all the things that should always happen and call the delegate to do the specifics.

Since the service's methods all take a request derived from APIRequest and return a response derived from APIResponse, they conform to Func<APIRequest, APIResponse>. Some methods, for example logout, take a request object that contains no information except the request header that identifies the session. I would like to be able to use my generic method, called Invoke, like this:

<br />
public void Logout()<br />
{<br />
    if (!HasSession) return;<br />
    var r = Invoke(globalService.logout);<br />
    ...<br />
}<br />
<br />
void keepAlive()<br />
{<br />
    // This runs on a background thread and makes a call to keep the session alive<br />
    // if it's close to 20 minutes since the last request.<br />
    TimeSpan margin = TimeSpan.FromSeconds(30);<br />
<br />
    while (HasSession)<br />
    {<br />
        if (sessionLifeLeft > margin) Thread.Sleep(sessionLifeLeft - margin);<br />
        Invoke(globalService.keepAlive);<br />
    }<br />
}<br />
<br />


I declared the following generic methods to make this possible (the implementation details aren't really important for our purposes here, but I include it as-is since I don't understand why it doesn't work the way I want it to):

<br />
protected TResponse Invoke<TRequest, TResponse>(Func<TRequest, TResponse> method) <br />
    where TRequest : APIRequest, new()<br />
    where TResponse : APIResponse<br />
{<br />
    return Invoke<TRequest, TResponse>(method, new TRequest());<br />
}<br />
<br />
<br />
protected TResponse Invoke<TRequest, TResponse>(Func<TRequest, TResponse> method, TRequest req) <br />
    where TRequest: APIRequest <br />
    where TResponse: APIResponse<br />
{<br />
    APIResponse r;<br />
    lock (this)<br />
    {<br />
        req.header = reqHeader;<br />
        r = method(req);<br />
        watch.Reset();<br />
        reqHeader.sessionToken = r.header.sessionToken;<br />
    }<br />
    return (TResponse)r;<br />
}<br />


I don't understand why I need to cast the return value; the compiler says I can't implicitly convert APIResponse to TResponse. I understand one can't do so in general, but since "method" returns TResponse already I don't understand why such a conversion would result from my code. But with the cast it builds, but when I try to use it as described above the compiler claims the type parameters "cannot be inferred from usage", which I think is weird since there are only two type parameters and both are well-defined from "method", which takes TRequest and returns TResponse.

I have a hunch this has something to do with me thinking in terms of the *formal* parameters rather than the *actual* (run-time) parameters. Still, I'm wondering if there is any way to achieve the desired outcome: to enable invoking the service operations without having to write the type parameters explicitly. It just isn't very elegant and looks rather redundant to code

<br />
Invoke<LogoutReq, LogoutResp>(globalService.logout);<br />


Can anyone think of a way to make the type inference work out as I wish, from the Func<t, tresult=""> types?
AnswerRe: Generics, delegates and type inference Pin
Gideon Engelberth2-Oct-09 6:29
Gideon Engelberth2-Oct-09 6:29 
GeneralRe: Generics, delegates and type inference Pin
dojohansen2-Oct-09 7:43
dojohansen2-Oct-09 7:43 
GeneralRe: Generics, delegates and type inference Pin
Gideon Engelberth2-Oct-09 13:00
Gideon Engelberth2-Oct-09 13:00 
QuestionInheritance question Pin
xkrja1-Oct-09 23:35
xkrja1-Oct-09 23:35 
AnswerRe: Inheritance question Pin
stancrm1-Oct-09 23:49
stancrm1-Oct-09 23:49 
GeneralRe: Inheritance question Pin
xkrja2-Oct-09 0:22
xkrja2-Oct-09 0:22 
GeneralRe: Inheritance question Pin
Mirko19802-Oct-09 0:57
Mirko19802-Oct-09 0:57 
AnswerRe: Inheritance question Pin
Christian Graus2-Oct-09 0:40
protectorChristian Graus2-Oct-09 0:40 
AnswerRe: Inheritance question Pin
DaveyM692-Oct-09 0:46
professionalDaveyM692-Oct-09 0:46 
AnswerRe: Inheritance question Pin
dojohansen3-Oct-09 1:12
dojohansen3-Oct-09 1:12 
QuestionStream System Sound to A GSM MODEM Pin
aghoshbabu1-Oct-09 23:09
aghoshbabu1-Oct-09 23:09 
AnswerRe: Stream System Sound to A GSM MODEM Pin
Rutvik Dave2-Oct-09 4:27
professionalRutvik Dave2-Oct-09 4:27 
QuestionDotNetOpenMail Authentication Pin
DotNetCoderJunior1-Oct-09 22:52
DotNetCoderJunior1-Oct-09 22:52 
AnswerRe: DotNetOpenMail Authentication Pin
Christian Graus1-Oct-09 23:05
protectorChristian Graus1-Oct-09 23:05 
GeneralRe: DotNetOpenMail Authentication Pin
DotNetCoderJunior1-Oct-09 23:23
DotNetCoderJunior1-Oct-09 23:23 
GeneralRe: DotNetOpenMail Authentication Pin
Tom Deketelaere2-Oct-09 0:25
professionalTom Deketelaere2-Oct-09 0:25 
GeneralRe: DotNetOpenMail Authentication Pin
dojohansen3-Oct-09 1:18
dojohansen3-Oct-09 1:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.