我有一个名为 IStrategy 的界面:
public interface IStrategy
{
}
我有另一个名为 IClickStrategy 的界面,它继承自 IStrategy 。它有一个名为 GetClicks()的方法:
public interface IClickStrategy : IStrategy
{
void GetClicks(string[] args);
}
一个继承自 IClickStrategy 并实现 GetClicks()方法的类:
public class UnionenClicksController : IClickStrategy
{
Models.DMDelivery.Unionen model;
Logger logger;
public UnionenClicksController()
{
this.model = new Models.DMDelivery.Unionen();
this.logger = new Logger();
}
public void GetClicks(string[] args)
{
...
}
}
在我的主要方法上,根据策略的类型,我想决定做什么。所以在我拥有的一切之前:
IStrategy strategy = null;
然后,如果输入参数想要获取点击信息,我想从我的班级 UnionenClicksController()调用GetClicks函数。
但是可以看出,我看不到 GetClicks()函数。但是,如果我将策略更改为 IClickStrategy ,那么它将会看到我的GetClicks。但这不是我想要的,因为除了点击之外我可能有不同的策略,我不想在我的主方法的开头声明它。
我做错了什么?感谢。
答案 0 :(得分:1)
IStrategy
不包含GetClicks
,它可以在IClickStrategy
界面中找到。
更改
IStrategy strategy = null;
到
IClickStrategy strategy = null;
您也可以尝试将其投射到合适的界面,
如果您确定它实现了正确的接口:
((IClickStrategy)strategy).GetClicks();
如果您不确定:
var s = strategy as IClickInterface;
if (s != null)
{
s.GetClicks();
}
答案 1 :(得分:1)
您必须为每个案例进行投射,或者在IStrategy
中选择正确方法的虚拟方法。
如果一个对象实现了几种策略,那么后一种解决方案是不可能的。
答案 2 :(得分:1)
IStrategy strategy = null;
.
.
. later on you find that you need to see if it contains a IClickStrategy ..
.
IClickStrategy clicker = strategy as IClickStrategy;
if(clicker != null) {
clicker.GetClicks(...);
}
答案 3 :(得分:0)
试试吧
IClickStrategy strategy = null;
因为UnionenClicksController没有继承IStrategy。
答案 4 :(得分:0)
当然可以。但是编译器不知道这一点。您只是告诉他,您希望将strategy
视为IStrategy
。你非常清楚这一点。现在...
不要将名称strategy
与您的UnionenClicksControler
对象混淆 - 它只是对象的名称。这个名字有一个类型。如果您想使用GetClicks()
方法,请执行以下操作:
(strategy as IClickStrategy).GetClicks(args);
我自己还没有尝试过这个,因为我没有去过,但是做了
dynamic strategy;
也可能解决您的问题...但您可能会放弃任何智能感知魔法......
答案 5 :(得分:0)
尝试使用:
if(strategy is IClickStrategy)
(strategy as IClickStrategy).GetClicks();
从技术上讲,您需要首先检查对象的类型,然后将其强制转换以查看继承接口的方法。
答案 6 :(得分:0)
感谢所有答案,但我找到了解决问题的两个方法:
首先,是不使用该行:
IStrategy strategy = null;
将其推迟到每个switch语句之后,然后将策略声明为IClickStrategy。
其次,如果我想保留我的 IStrategy strategy = null; 行,我会在我的IStrategy界面中将GetClicks方法移动一级并给它一个更通用的名称: GetItems 强>
现在我的开关盒看起来像这样:
case "GETCLICKSUNIONEN":
strategy = new UnionenClicksController();
strategy.GetItems(args);
break;