如何将泛型类作为参数传递给非泛型类构造函数

6
假设有以下代码(请在最后一个类的注释中阅读我的问题):
//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()
    {}
}

你为什么不想使用通用的SynchRequest? - AnthonyWJones
你能谈谈在Execute()中如何使用info成员吗?这可能为功能等效的答案提供基础。 - joshperry
因为SynchRequest类被项目中的其他类调用,而且它的目的是运行服务,而不提供有关客户端信息的任何类型。此外,还有一些使用SynchRequest的类,它们不指定或需要任何客户端信息。因此,将该类变成通用类并不是一个好方法。(SynchRequest还有另一个空构造函数) - Ioannis
执行方法从clientRequestInfo类中读取参数并将请求发送到服务器。因此,它将序列化clientRequestInfo类并将其发送到服务器。 - Ioannis
我很惊讶没有人提到工厂模式。创建一个静态方法,它的作用类似于命名构造函数。 - nawfal
4个回答

7
如果您不想使 SynchRequestInfo 成为通用的,那么您可以为 ClientRequestInfo 创建一个非通用的基类吗?--
public abstract class ClientRequestInfo
{
    public abstract void NonGenericMethod();
}

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

然后:

public class SynchRequest
{
    private ClientRequestInfo info;

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

    public void Execute()
    {
        // ADDED: for example
        info.NonGenericMethod();
    }
}

如果CreateRequestAlphaCreateRequestBeta需要调用Execute方法,那么它当然需要在基类中声明。 - Rob Kennedy
“Execute” 是 SynchRequest 的一部分,而不是 ClientRequestInfo - Ben M

2

如果您想要通用的成员变量,类必须是通用的。

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

是一个通用成员。

您可以使用非泛型的基类或接口:

class ClientRequestInfo<K,Y> : IClientRequestInfo

但在您的示例中,ClientRequestInfo没有任何非泛型成员,因此接口/基类将为空,并且必须转换为正确的泛型版本才能有用。


1

如果您不想使SynchRequestInfo成为泛型,有两个选择:

  1. 创建一个非泛型的基类,让它们都使用。
  2. 提供一个接口来使用,例如ISynchInfo,并让您的泛型类实现该接口。

在这种情况下,我更喜欢接口方法,因为您将来可能想要同步其他类型(与客户端请求分离)。


1

让ClientRequestInfo(K,V)实现一个ClientRequestInfo接口,该接口包含SynchRequest所需的接口函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接