泛型类型实例中泛型类型的属性 - 链接泛型类型

时间:2013-10-20 12:02:02

标签: c# generics covariance contravariance

对不起,我不确定这个最好的标题是什么......

我是.NET编程的新手(有一点Java背景),我尝试开发一个简单的类型化处理队列。

我把我的对象放在第一个ActionQueue中。通过内部逻辑,IAction中只有一个ActionQueue处理对象并将其推送到下一个ActionQueue。每个ActionQueue都以TaskBlockingCollection为燃料(但这并不重要):

Object
...
ActionQueue[IPrepare, IPrepare]
...
ActionQueue[IDownload, IDownload]
...
ActionQueue[ISave]
...
ProcessedObject

我努力实现的目标是:

  • 使ActionQueue通用,因此只能为作业注册相同子接口的IActions(我使用List<T>存储操作)
  • Next属性将ActionQueue上的输出与另一个ActionQueue的输入绑定

我的简化代码如下:

# SETUP

interface IPrepare: IAction {}
interface IDownload: IAction {}
interface ISave: IAction {}

public interface IActionQueue<in T> where T: IAction {
    IActionQueue<IAction> Next {get;set;} # it can be any action queue
    void Register(T action);
    void Run();
}

class PrepareFromDb : IPrepare {...}
class PrepareFromSettings : IPrepare {...}
class DownloadLocal : IDownload{...}
class DownloadHttp : IDownload{...}
class SaveLocal: ISave {...}

# IN MAIN METHOD

ActionQueue<IPrepare> prepareActions = new ActionQueue<IPrepare>();
prepareActions.Register(new PrepareFromDb(config));
prepareActions.Register(new PrepareFromSettings());

ActionQueue<IDownload> downloadActions = new ActionQueue<IDownload>();
downloadActions.Register(new DownloadLocal());
downloadActions.Register(new DownloadHttp());

ActionQueue<ISave> saveActions = new ActionQueue<ISave>();
saveActions.Register(new SaveLocal(RootPath));

# TRICKY PART THAT FAILS

prepareActions.Next = downloadActions # pass `prepare`d items to `download` queue
downloadActions.Next = saveActions # pass `download`ed items to `save` queue

如果我将IActionQueue声明为interface ITrackQueue<out T> where T: ITrackTransformer(注意 out ),则Main函数不显示错误,但void Register(T action)现在显示错误。< / p>

因为它是内部库的代码而且我是唯一的用户,所以我可以删除所有通用的东西并编译它。但我总是尽量严格编码。

或者我可以将ActionQueue的内部BlockingCollection队列用作Next属性,但我不喜欢泄漏内部实现,因为它打破了封装。

所以问题是。实现这一目标的最类型安全的方法是什么?

0 个答案:

没有答案