我正在玩一种工厂,装饰和责任链的混搭。基本上,我正在建立一个接收请求对象的工厂,对其进行分析,并将其进一步传递到更具体的内部工厂。我已到达下面的结构,但它有问题。
public abstract class AbstractFactoryRequest { }
public class SpecificFactoryRequest : AbstractFactoryRequest { }
public class MoreSpecificFactoryRequest : SpecificFactoryRequest { }
public interface IThing { }
public interface IThingFactory<in T> where T : AbstractFactoryRequest
{
IThing GetThing(T request);
}
public abstract class AbstractThingFactory<T> : IThingFactory<T> where T : AbstractFactoryRequest
{
public IThing GetThing(T request)
{
var innerFactory = GetInnerFactory(request);
return innerFactory.GetThing(request);
}
protected abstract IThingFactory<T> GetInnerFactory(T request);
}
public class SpecificThingFactory : AbstractThingFactory<SpecificFactoryRequest>
{
protected override IThingFactory<SpecificFactoryRequest> GetInnerFactory(SpecificFactoryRequest request)
{
return (IThingFactory<SpecificFactoryRequest>)new MoreSpecificThingFactory();
}
}
public class MoreSpecificThingFactory : AbstractThingFactory<MoreSpecificFactoryRequest>
{
protected override IThingFactory<MoreSpecificFactoryRequest> GetInnerFactory(MoreSpecificFactoryRequest request)
{
// return an even more specific factory...
}
}
尝试从MoreSpecificThingFactory
内返回新SpecificThingFactory
时出现问题。如上所述,ReSharper将其称为可疑演员,如果没有演员表,编译器会说在MoreSpecificThingFactory和IThingFactory之间没有隐式转换。我原以为这可能会有效,因为继承就在那里。有办法解决这个问题吗?
答案 0 :(得分:1)
您收到此错误是因为您将参数声明为contravariant,这意味着您只能将其用作一种方法参数,而不能用作接口方法的返回类型。以下是an article关于泛型类型的差异。
现在想想你正在尝试做什么。如果你转换为不太具体的类型,这意味着你可以将较少的特定参数传递给只接受更具体参数的方法,你显然不能这样做。
要进行此演员表,您应该按如下方式定义MoreSpecificThingFactory:
public class MoreSpecificThingFactory : AbstractThingFactory<SpecificFactoryRequest>
{
protected override IThingFactory<SpecificFactoryRequest> GetInnerFactory(SpecificFactoryRequestrequest)
{
if (request is MoreSpecificFactoryRequest)
{
// return an even more specific factory...
}
// throw an exception or do something else
}
}
修改强>
您似乎需要在此处应用chain of responsibility模式