6

Assume the following code (Please read my question in the code comments in the final class):

//This is my Generic Class
public class ClientRequestInfo<K, V>
{
    public string Id { get; set; }
    private Dictionary<K, V> parameters;

    public ClientRequestInfo()
    {
        parameters = new Dictionary<K, V>();
    }

    public void Add(K key, V value)
    {
        parameters.Add(key, value);
    }
 }

public class ProcessParameters()
{
    private void CreateRequestAlpha()
    {
        ClientRequestInfo<int, string> info = new ClientRequestInfo<int, string>();
        info.Add(1, "Hello");
        SynchRequest s = new SynchRequest(info);
        s.Execute();
    }
    private void CreateRequestBeta()
    {
        ClientRequestInfo<int, bool> info = new ClientRequestInfo<int, bool>();
        info.Add(1, true);
        SynchRequest s = new SynchRequest(info);
        s.Execute();
    }
}

public class SynchRequest
{
    //What type should I put here?
    //I could declare the class as SynchRequest<K, V> but I don't want
    //To make this class generic.
    private ClientRequestInfo<????,?????> info;
    private SynchRequest(ClientRequestInfo<?????,?????> requestInfo)
    {
        //Is this possible?
        this.info = requestInfo;
    }

    public void Execute()
    {}
}
sth
  • 222,467
  • 53
  • 283
  • 367
Ioannis
  • 2,985
  • 4
  • 25
  • 19
  • Why don't you want to use a generic SynchRequest? – AnthonyWJones Sep 29 '09 at 17:06
  • Can you talk about what you would do in Execute() with the info member? This may provide a basis for a functional equivalent answer. – joshperry Sep 29 '09 at 17:12
  • Because the class SynchRequest is called by other classes of the project and the purpose of SynchRequest is to run the service and not provide any type about client information. Also there are classes that use SynchRequest and do not specify or require any client info. So is not good approach to make this class generic. (SynchRequest has another empty constructor) – Ioannis Sep 29 '09 at 17:16
  • The execute method reads the parameters from clientRequestInfo class and sends the request to the server. So it will serializes the class clientRequestInfo and send it to server. – Ioannis Sep 29 '09 at 17:18
  • I am surprised nobody mentioned Factory approach. Create a static method that acts like a named constructor. – nawfal Sep 21 '20 at 02:51

4 Answers4

7

If you don't want to make SynchRequestInfo generic, can you make a non-generic base class for ClientRequestInfo? --

public abstract class ClientRequestInfo
{
    public abstract void NonGenericMethod();
}

public class ClientRequestInfo<K, V> : ClientRequestInfo
{
    public override void NonGenericMethod()
    {
        // generic-specific implementation
    }
}

Then:

public class SynchRequest
{
    private ClientRequestInfo info;

    private SynchRequest(ClientRequestInfo requestInfo)
    {
        this.info = requestInfo;
    }

    public void Execute()
    {
        // ADDED: for example
        info.NonGenericMethod();
    }
}
Ben M
  • 22,262
  • 3
  • 67
  • 71
  • The `Execute` method would of course need to be declared in the base class if `CreateRequestAlpha` and `CreateRequestBeta` are to be able to call it. – Rob Kennedy Sep 29 '09 at 17:08
  • `Execute` is part of `SynchRequest`, not `ClientRequestInfo`. – Ben M Sep 29 '09 at 17:09
2

The class has to be generic if you want generic member variables.

private ClientRequestInfo<????,?????> info;

Is a generic member.

You can use a non-generic base class or interface:

class ClientRequestInfo<K,Y> : IClientRequestInfo

But in your example, ClientRequestInfo doesn't have any non-generic members, so the interface/base class would be empty and have to be casted to the correct generic version to be useful anyway.

Rex M
  • 142,167
  • 33
  • 283
  • 313
1

You have two options, if you want to not make SynchRequestInfo generic.

  1. Make a non-generic base class, having both use it.
  2. Provide an interface to use, such as ISynchInfo, and have your generic class implement the interface.

In this case, I'd prefer the interface approach, since you may want to synchronize other types (separate from client requests) in the future.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

Make ClientRequestInfo(K,V) implement a ClientRequestInfo interface with the interface functions SynchRequest will needs.

Coincoin
  • 27,880
  • 7
  • 55
  • 76