参数化通用接口 – 创建一个Dictionary <Type,Interface >?

对不起,标题令人困惑,我不知道我说的是对的,不知道这个叫做什么……如果你想要的话,请在阅读问题后随意编辑。

当我注意到有很多地方可以使用策略模式时,我正在重构我的旧代码。 我有一个库存系统和物品 – 有多种方法可以添加物品 – 正常方式,有力的方式等等。您还可以用多种方式再次交换物品 – 所以我认为那些是好地方使用那种模式。

这是我有的,用于添加项目:

public interface IAddingStrategy where T : AddArgs { bool Add(T args); } public class NormalAdd : IAddingStrategy { public bool Add(NormalAddArgs args) { // normal adding logic... } } public class ForceAdd : IAddingStrategy { public bool Add(ForceAddArgs args) { // force adding logic... } } // other strategies... public abstract class AddArgs { } public class NormalAddArgs : AddArgs { public readonly param1 p1; public readonly param2 p2; etc; public NormalAddArgs(param1 p1, param2 p2, etc) { this.p1 = p1; this.p2 = p2; this.etc = etc; } } public class ForceAddArgs : AddArgs { public param3 p3; public ForceAddArgs(param3 p3) { this.p3 = p3; } } // other adding args... 

现在我正在尝试做什么 – 但不知道该怎么做,是:

 public class Adder { private Dictionary dic = new Dictionary(); public Adder() { dic.Add(typeof(NormalAdd), new NormalAdd()); dic.Add(typeof(ForceAdd), new ForceAdd()); dic.Add(typeof(EtcAdd), new EtcAdd()); } } 

什么应该是什么? 我希望它是任何添加策略 – 但如果我去IAddingStrategy – 它不起作用,因为它要求我指定参数,如果我这样做,字典不能保存所有可能类型的策略。 ..;(

任何想法如何去做? 什么应该是什么? 在这种情况下,我是否正确使用策略模式? 如果没有,最好的办法是什么?

感谢你的帮助。

编辑:解决这个问题的方法是这样的:

 public interface IAddingStrategy { void Add(AddArgs args); } public class NormalAdd: IAddingStrategy { public void Add(AddArgs args) { if (args is NormalAddArgs) // normal add logic } } public class ForceAdd: IAddingStrategy { public void Add(AddArgs args) { if (args is ForceAddArgs) // force add logic } } 

然后字典就是

但实际上,我不喜欢if ,它只是感觉不对 – 如果有人通过错误类型的arg怎么办? 这是在运行时才检测到的东西,我想在编译时检测到这个东西。 – 使用generics我能够实现这一点。

根据我的评论:最小化通用接口的暴露可能是有意义的,而不是要求调用者链的generics参数。 一种方法是实现通用和非通用接口。

优点:

  • 您现在可以使用非通用接口。
  • 合理的类型安全(大多数情况下)。

缺点:

  • 演员是必需的。
  • 每个方法都需要两个实现。
  • 编译器无法保证类型安全。
 /// Some common base type. public interface IAddArgs {} /// Non-generic interface. public interface IAddingStrategy { void Add( IAddArgs obj ); } /// Generic version. ///  public interface IAddingStrategy : IAddingStrategy where T : IAddArgs { void Add( T obj ); } public class NormalAddArgs : IAddArgs {} public class NormalAdd : IAddingStrategy { public void Add( NormalAddArgs obj ) { } public void Add( IAddArgs obj ) { Add( (NormalAddArgs)obj ); } } 

这确实留下了如何创建正确类型的参数的唠叨问题,即哪个类有足够的信息来创建NormalAddArgs的实例,以便它可以传递给适当的策略?

一种方法是要求每种类型为您创建这些类型:

 /// Non-generic interface. public interface IAddingStrategy { void Add( IAddArgs obj ); // "context" can be a type that provides additional info IAddArgs CreateAddArgs( object context ); } public class NormalAdd : IAddingStrategy { public void Add( NormalAddArgs obj ) { } public void Add( IAddArgs obj ) { Add( (NormalAddArgs)obj ); } public IAddArgs CreateAddArgs( object context ) { return new NormalAddArgs(); } } 

我认为你不能在你的情况下有一个Dictionary> ,因为你需要定义T对于字典中的所有值都是通用的。

Jon Skeet给出了一个类似问题的优秀答案: 通用字典,其值为带有通用引用的接口 。 我希望它也能帮到你。