这是我的示例界面:
public interface IJob<T, R>
where T : IStep
where R : IDelivery
{
T Step { get; set; }
R Delivery { get; set; }
}
这是我的示例实现
public class ImageJob<T, R> : IJob<T, R>
where T : ImageStep
where R : ImageDelivery
{
public T Step { get; set; }
public R Delivery { get; set; }
}
ImageStep 和 ImageDelivery 都会实现各自的界面(IStep,IDelivery)
现在我要做的是连接我的所有存储库方法。我们以这种方法为例:
public void CreateJob(IJob<IStep, IDelivery> job);
所以我创建了一个新的:
var job = new ImageJob<ImageStep, ImageDelivery>
{
...
}
然后我尝试将其传递给存储库方法:
repository.CreateJob(job);
我得到一个错误说:
Unable to cast ImageJob<ImageStep, ImageDeliver> to type IJob<IStep, Idelivery>
有人可以向我解释为什么这会引发错误吗?我实施和接口是完全错误的吗?
对于我正在尝试做的事情,是否有优雅的解决方案?
我想用不同的步骤和交付方法等抽象出每个作业。这可能是其他方式吗?或者我完全错过了什么?
答案 0 :(得分:4)
我认为可以使用协方差。这使您可以将特定的Generic类型转换为其通用接口或基类之一,如:
MyType<object> list = new MyType<MyType>;
类和接口decleration:
public interface IMyType<out T>{...}
public class MyType<T> : IMyType<T> {...}
Generic decleration中的“out”关键字启用强制转换。
Here是MSDN上的一个很好的页面,它可以帮助您进一步
在你的情况下,它会是(如果你没有在界面中设置setter
public interface IJob<out T, out R>
where T : IStep
where R : IDelivery
{
T Step { get; }
R Delivery { get; }
}
这适用于您实施的课程
答案 1 :(得分:2)
我认为IJob
的声明需要
public interface IJob<T, R>
where T : IStep
where R : IDelivery
{
T Step { get; set; }
R Delivery { get; set; }
}
否则,T
和R
参数从不在界面中使用,IJob
实际上是非泛型的。除此之外,为清楚起见,您可能需要为类型参数TStep
和TDelivery
命名。