我确信这是重复但我不确定我正在寻找正确的答案。或者理解它回答了我的问题。
对于1我认为我使用我的界面错了。对于1我打破了SOLID的规则,并试图清理它。例如IReelWindow
。我有ReelWindowTumble
特定的内容,其他ReelWindows
不使用并抛出未实现的错误。我开始将其分解为多个接口,但发现我不再能够访问ReelWindowTumble
的函数,即使我为ITumble
创建了一个新接口,但仍然继承自IReelWindow
。问题在于功能代码。
public interface IReelWindow
{
//stuff declared
void PopulateWindowTumble();
void PopulateWindow(int[] currentStops);
}
public class ReelWindow : IReelWindow
{
// implements most of it throwing exceptions when I don't use it.
public void PopulateWindow(int[] currentStops)
{
}
public void PopulateWindowTumble()
{
throw new NotImplementedException();
}
}
public class ReelWindowTumble : IReelWindow
{
// implements most of it throwing exceptions when I don't use it.
public void PopulateWindow(int[] currentStops)
{
}
void PopulateWindowTumble()
{
}
}
public class ReelWindowIndependent : IReelWindow
{
// implements most of it throwing exceptions when I don't use it.
public void PopulateWindow(int[] currentStops)
{
}
public void PopulateWindowTumble()
{
throw new NotImplementedException();
}
}
在这里,我声明一个新的IReelWindow
并根据客户端输入创建一个新的ReelWindow
。这项工作正常,因为我只是将IReelWindow
传递给我想要使用ReelWindow的地方。
我不认为这是我的界面的正确用法。如果我使用ICloneable
,我就不会声明ICloneable
的新对象并传递它。
但我的目的是创建一个通用ReelWindow
类型。我不在乎客户创建什么类型的窗口。我只是想强制执行它应该具有的功能,因为我特别使用它们
如何声明我可以传递的通用ReelWindow
,而不创建多个相同但传入强类型的函数?
public static IReelWindow CreateReelWindow(WindowType userSelectedWindowType, Paytable paytable)
{
IReelWindow _reelWindow;
if (userSelectedWindowType == WindowType.Standard)
{
_reelWindow = new ReelWindow(paytable.ColLengths, paytable.ReelContainer.Reels, paytable.WindowWidth, paytable.Lineset, paytable.ReelContainer.TotalPhysicalReelStop);
}
else if (userSelectedWindowType == WindowType.Tumble)
{
_reelWindow = new ReelWindowTumble(paytable.ColLengths, paytable.ReelContainer.Reels, paytable.WindowWidth, paytable.Lineset, paytable.ReelContainer.TotalPhysicalReelStop);
}
else if (userSelectedWindowType == WindowType.Independent)
{
_reelWindow = new ReelWindowIndependent(paytable.ColLengths, paytable.ReelContainer.Reels, paytable.WindowWidth, paytable.Lineset, paytable.ReelContainer.TotalPhysicalReelStop, paytable.ReelLengths, paytable.ReelStarts);
}
else
throw new ApplicationException("Unknown window type selected by user. Cannot continue.");
return _reelWindow;
}
稍后在我的代码中我使用了reelwindows,并且只传入了' IReelWindow'因为我不关心什么类型的卷轴窗口,所以函数会相应地使用它。
public abstract class AEval
{
public abstract double Evaluate(IReelWindow reelWindow, ref string flags, int currentStopsWeight);
public abstract double EvaluateVerbose(IReelWindow reelWindow, ref string flags, int currentStopsWeight);
}
答案 0 :(得分:0)
您传递的对象是_reelWindow,虽然它实现了IReelWindow,但它不是IReelWindow对象。相反,它是您的派生类型之一:ReelWindow,ReelWindowTumble,ReelWindowIndependent等。每个派生类型应由您的客户端处理相同(如您所述)。
让我们假装ReelWindow从接口实现2个方法,ReelWindowTumble从接口实现3个方法,ReelWindowIndependent从接口实现10个方法。并且该接口最多有10种方法可供实现。
使用你的例子的语言,这意味着ReelWindow将有8个方法使用NotImplementedException(NIE),ReelWindowTumble将有7个方法NIE,而ReelWindowIndependent有0个方法NIE。
您的客户代码怎么样?好吧,所有这一切都有意义,你的客户端代码应该在使用_reelWindow时调用所有10个接口方法。这也意味着,使用我的例子,ReelWindowIndependent应该可以正常使用客户端代码,因为它没有NIE方法。
我说你真正的问题是NIE。删除这些异常,而是返回null。然后,在您的客户端代码中,在控制流程中,您可以添加语句到"如果返回的对象为空,请跳过本节"。
请记住,所有对象都继承自'对象'。您界面中的那些强类型返回对象可以作为' object'返回。太。这意味着任何强类型对象都可以设置为null。重复:尝试为具有强类型返回值的方法返回null值,并在客户端代码中处理null。现在,如果接口方法没有返回 - 它被标记为void - 那么您不必担心在客户端代码中检查null,也不需要NIE:该方法可以留空并且在字面上调用时什么也没做。如果您考虑这一点,您可能会努力寻求不使用强类型返回值的界面设计。这就是Jamiec的评论:我们需要更多地了解界面。