John Ohara
John Ohara

Reputation: 2901

How to pass generic in an interface (nested generics)

I don't know whether I'm approaching this from the right angle or not, but either way I can't find syntax that works.

I want to pass 3 generic types to a method - from there I'll use reflection to create objects when I need them. However the object I'm passing is itself generic.

It sort of sounds like nested generics.

Let's say I create an interface:

    public interface IAgent<TRequest, TClient, TResponse>
    {
    }

I have a class like this that implements IAgent:

public class MyClass : IAgent<?>

Then I want to call a method something like this:

public method MyMethod<T>(T obj) where T : IAgent<?>
{
    // do somethings here
}

UPDATE

Here's what I currently do at class level.

public sealed class T3Agent
    : AppAgent<T3RequestAdapter, T3WebClient, T3ResponseAdapter>
{
}

public abstract class AppAgent<TRequest, TClient, TResponse>
    where TRequest : IAgentRequestAdapter
    where TClient : CustomWebClient
    where TResponse : IAgentResponseAdapter
{
    public AppResponse Submit(IAppForm appForm, ServiceLog log)
    {
    }
}

public sealed class AppManager
{
    public AppResponse Submit()
    {
        var t3 = new T3Agent();
        var t3Result = t3.Submit(Form, Log);

        return t3Result;
    }
}

In the final method, I instantiate a new class (T3Agent), but this is tightly coupled to T3. I want to be able to instantiate AppAgent once and pass the required generic types through the method rather than the class, so that I can reuse the class.

Upvotes: 0

Views: 153

Answers (2)

andreasV
andreasV

Reputation: 11

I think you have 2 options:

  1. if you have to work with generic class T from Agent<T> you have to know the type anyway so you have to put it in your generic declaration (see TypeNeeded() method below)
  2. If it is not necessary, then split up the interface in a not generic and in a generic interface and then let IAgent<T> extend IAgent (IAgent<T>: IAgent). Now you can create a method without to know the type for IAgent<T> (see method DoSomething())

    public interface IAgent
    {
        void Action( );
        int Calculate( );
    }
    
    public interface IAgent< T > : IAgent
    {
      void Set( T value );
    }
    
    public class MyClass
    {
        public void DoSomething< T >( T agent ) where T : IAgent
        {
            //...
        }
    
        public void TypeNeeded< T, V >( T agent ) where T : IAgent<V>
        {   
        }
    }
    

Upvotes: 1

nvoigt
nvoigt

Reputation: 77364

If you don't know the types for your generic interface yet, your class or method needs to be generic, too:

public class MyClass<TRequest, TClient, TResponse> : IAgent<TRequest, TClient, TResponse>
{
}

Or for the method:

public void MyMethod<T, TRequest, TClient, TResponse>(T obj) where T : IAgent<TRequest, TClient, TResponse>
{
    // do somethings here
}

Upvotes: 0

Related Questions