【问题标题】:How to pass a Generic class as a Parameter to a non-generic class constructor [duplicate]如何将泛型类作为参数传递给非泛型类构造函数[重复]
【发布时间】:2009-09-29 17:02:05
【问题描述】:

假设以下代码(请阅读我在最后一课代码 cmets 中的问题):

//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()
    {}
}

【问题讨论】:

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

标签: c# generics parameter-passing


【解决方案1】:

如果您不想使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 方法,当然需要在基类中声明它。
  • ExecuteSynchRequest 的一部分,而不是ClientRequestInfo
【解决方案2】:

如果您想要泛型成员变量,则该类必须是泛型的。

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

是通用成员。

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

class ClientRequestInfo<K,Y> : IClientRequestInfo

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

【讨论】:

    【解决方案3】:

    如果您不想使 SynchRequestInfo 通用,您有两个选择。

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

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

    【讨论】:

      【解决方案4】:

      使 ClientRequestInfo(K,V) 使用 SynchRequest 需要的接口函数实现 ClientRequestInfo 接口。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-28
        • 1970-01-01
        相关资源
        最近更新 更多