Tech Off Thread

5 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

How to retreive generic type?

Back to Forum: Tech Off
  • User profile image
    phreaks

     
    public delegate T Execute<T>(T param);
    public virtual void Process<T>(Execute<T> method, T param)
    {
        IAsyncResult result = method.BeginInvoke(param, ExecuteCallback, method);
    }
     
     
    protected virtual void CBback(IAsyncResult result)
    {
        Object returnValue = null;
        Object exec = result.AsyncState;
        returnValue = ((Execute<Object>)exec).EndInvoke(result);
    }
     
    //=============== implementation ===============
    Mock mock = new Mock();
    Execute<Int32> exec = new Execute<Int32>(mock.FakeCount); // mock.FakeCount actually takes an int
    cDispatcher.Process<Int32>(exec, 69); // This will fail due to type casting in the CB method above. 
    
    //================================================
     
    

     

     

     

    The problem is in the definition of CB.

    Execute is hardcoded to expect an Object, but the method it executes may take a different type param.

     

    I am able to get around this by creating derived classes and overriding CB with a specific implementation for each type. There are obvious problems with that approach though.

     

    Ideas?

     

     

     

  • User profile image
    Sven Groot

    Just make ExecuteCallback a generic method as well, e.g. ExecuteCallback<T>, and pass it as such to BeginInvoke.

     

    As an aside, you don't need to pass the delegate in the async state. In the callback, you can cast result to System.Runtime.Remoting.Messaging.AsyncResult, and use its AsyncDelegate property to get the delegate.

  • User profile image
    phreaks

    Sven Groot said:

    Just make ExecuteCallback a generic method as well, e.g. ExecuteCallback<T>, and pass it as such to BeginInvoke.

     

    As an aside, you don't need to pass the delegate in the async state. In the callback, you can cast result to System.Runtime.Remoting.Messaging.AsyncResult, and use its AsyncDelegate property to get the delegate.

    Thanks. I tried that but I get a compile error...

     

    Cannot convert type 'T' to 'System.Runtime.Remoting.Messaging.AsyncResult'

     

     

     
    
    
    protected virtual void ExecuteCallback<T>(T result)
    {
    Object returnValue = null;
    result = (System.Runtime.Remoting.Messaging.AsyncResult)result;
    
    Execute<T> exec = (System.Runtime.Remoting.Messaging.AsyncResult)result.AsyncState;
    
    returnValue = ((Execute<Object>)exec).EndInvoke(result);
    
    } 
    
    
    
    

     

     

     

     

     

  • User profile image
    Sven Groot

    phreaks said:
    Sven Groot said:
    *snip*

    Thanks. I tried that but I get a compile error...

     

    Cannot convert type 'T' to 'System.Runtime.Remoting.Messaging.AsyncResult'

     

     

     
    
    
    protected virtual void ExecuteCallback<T>(T result)
    {
    Object returnValue = null;
    result = (System.Runtime.Remoting.Messaging.AsyncResult)result;
    
    Execute<T> exec = (System.Runtime.Remoting.Messaging.AsyncResult)result.AsyncState;
    
    returnValue = ((Execute<Object>)exec).EndInvoke(result);
    
    } 
    
    
    
    

     

     

     

     

     

    That's not right at all. Try this:

     

    protected virtual void ExecuteCallback<T>(IAsyncResult result)
    {
        System.Runtime.Remoting.Messaging.AsyncResult asyncResult = 
            (System.Runtime.Remoting.Messaging.AsyncResult)result;
        Execute<T> method = (Execute<T>)asyncResult.AsyncDelegate;
        object returnValue = method.EndInvoke(result);
    }

  • User profile image
    phreaks

    Sven Groot said:
    phreaks said:
    *snip*

    That's not right at all. Try this:

     

    protected virtual void ExecuteCallback<T>(IAsyncResult result)
    {
        System.Runtime.Remoting.Messaging.AsyncResult asyncResult = 
            (System.Runtime.Remoting.Messaging.AsyncResult)result;
        Execute<T> method = (Execute<T>)asyncResult.AsyncDelegate;
        object returnValue = method.EndInvoke(result);
    }

    Yeah, that's the ticket.

     

    Thank you!

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.