【问题标题】:Factory pattern return generic types in c#工厂模式在 C# 中返回泛型类型
【发布时间】:2018-02-09 14:11:04
【问题描述】:
public interface IRequestProcessor<out T>
{    
   T Translate(string caseId);
}

public class xyzReqProcessor : IRequestProcessor<xyzType>
{
  public xyzType Process(string xyzMsg)
  {
     return new xyz();
  }
}
public class VHDReqProcessor : IRequestProcessor<VHDType>
{
  public VHDType Process(string xyzMsg)
  {
     return new VHD();
  }
}

直到这里看起来不错。 现在我想用工厂初始化类,但它不能返回 IRequestProcessor 类型的对象。

public static IRequestProcessor Get(FormType translatorType)
{

  IRequestProcessor retValue = null;
  switch (translatorType)
  {
    case EFormType.VHD:
      retValue = new VHDProcessor();
      break;
    case EFormType.XYZ: 
      retValue = new XYZProcessor();
      break;
  }
  if (retValue == null)
    throw new Exception("No Request processor found");

  return retValue;

}

在调用 Factory.Get(FormType translateType) 方法时,我不想指定任何固定对象类型,如下所示

Factory.Get(FormType translateType)

【问题讨论】:

  • 你可以声明它返回IRequestProcessor&lt;object&gt;。但是调用者必须转换调用Translate(或Process;问题不一致)的结果。
  • 如果在编译时不知道类型,就不能使用强类型。
  • @JonSkeet :不,如果我想使用 Object,那么我可以简单地使用它而无需泛型。
  • 那么,您如何期望从仅在 执行 时才知道的值返回 编译时安全 值?如果我打电话给FormType type = GetFormTypeFromSomewhere(); var processor = Factory.Get(type);,你希望processorcompile-time 类型是什么?
  • 但是帖子中没有显示 IRequestProcessor 类型......并且帖子中类型之间唯一共同的基本类型是'object'

标签: c# .net generics interface factory-pattern


【解决方案1】:

我不确定这个解决方案是否适合您的整体设计,但通过这个技巧,您可以实现您所要求的。关键是要有两个接口,一个是通用接口,一个不是非通用接口路由调用通用接口的地方。见下文:

public abstract class BaseType
{
    public abstract void Execute();
}

public class VhdType : BaseType
{
    public override void Execute()
    {
        Console.WriteLine("Vhd");
    }
}

public class XyzType : BaseType
{
    public override void Execute()
    {
        Console.WriteLine("Xyz");
    }
}

public interface IRequestProcessor
{
    BaseType Process();
}

public interface IRequestProcessor<T> : IRequestProcessor where T : BaseType, new()
{
    T Process<TInput>() where TInput : T;
}

public class VhdRequestProcessor : IRequestProcessor<VhdType>
{
    public BaseType Process()
    {
        return Process<VhdType>();
    }

    public VhdType Process<TInput>() where TInput : VhdType
    {
        return new VhdType();
    }
}

public class XyzRequestProcessor : IRequestProcessor<XyzType>
{
    public BaseType Process()
    {
        return Process<XyzType>();
    }

    public XyzType Process<TInput>() where TInput : XyzType
    {
        return new XyzType();
    }
}

public class RequestFactory
{
    public IRequestProcessor GetRequest(string requestType)
    {
        switch (requestType)
        {
            case "vhd": return new VhdRequestProcessor();
            case "xyz": return new XyzRequestProcessor();
        }

        throw new Exception("Invalid request");
    }            
}

使用示例:

IRequestProcessor req = new RequestFactory().GetRequest("xyz");
BaseType r = req.Process();
r.Execute();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多