首先,如果已经提出要求,我会道歉。我很难将问题用语言表达出来。因此,如下面的代码段所示,我有一个接口ISomeInterface
,其函数CalculateSomething
作为参数ICalculationInput
。我有多种类型实现ISomeInterface
,每个实现都需要与CalculateSomething
略有不同的参数。因此CalculateSomething
接受ICalculationInput
而不是特定参数。现在在函数CalculateSomething
的每个实现中,我都被迫在使用之前将其强制转换为特定类型,这使得代码有点难看。我想听听你对如何重新设计这一点的意见,所以我不必投出参数,这样我就可以避免运行时错误,并且在我读完代码后再次阅读我的代码时不会感到尴尬年。
interface ISomeInterface
{
void CalculateSomething(ICalculationInput input);
}
class SpecificClass : ISomeInterface
{
public void CalculateSomething(ICalculationInput input)
{
var spInput = ICalculationInput as SpecificInput;
if(spInput == null) throw ...
}
}
答案 0 :(得分:2)
如果设计SpecificClass
无法希望CalculateSomething
适用于SpecificInput
以外的任何其他内容,则通常应使用CalculateSomething(SpecificInput)
方法,而不是CalculateSomething(ICalculationInput)
方法} 方法。有时实际问题会妨碍,但在此不是这样。如果ISomeInterface
仅由该类实现,则很容易:只需更改界面即可。否则,如果某些类需要某些特定的输入类,而其他类需要不同的特定输入类,则参数化为:
interface ISomeInterface<T>
{
void CalculateSomething(T input);
}
class SpecificClass : ISomeInterface<SpecificInput>
{
public void CalculateSomething(SpecificInput input)
{
...
}
}
或者,如果有意义,您可以在界面中添加where T : ICalculationInput
约束。
如果由于某种原因你无法改变界面,你仍然可以使用基类为这些方法提供单一的通用实现,如下所示:
interface ISomeInterface
{
void CalculateSomething(ICalculationInput input);
}
abstract class SomeInterfaceBase<T> : ISomeInterface
{
public abstract void CalculateSomething(T input);
void ISomeInterface.CalculateSomething(ICalculationInput input)
{
var concreteInput = input as T;
if (concreteInput == null)
{
if (input == null)
throw new ArgumentNullException("input");
else
throw new ArgumentException("input must be a T", "input");
}
CalculateSomething(concreteInput);
}
}
class SpecificClass : SomeInterfaceBase<SpecificInput>
{
public override void CalculateSomething(SpecificInput input)
{
...
}
}
我怀疑上面有一些小错误,但这个概念应该是可行的。