处理接受基类型的函数中的派生类型

时间:2014-12-03 11:33:16

标签: c#

首先,如果已经提出要求,我会道歉。我很难将问题用语言表达出来。因此,如下面的代码段所示,我有一个接口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 ...
    }
}

1 个答案:

答案 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)
    {
        ...
    }
}

我怀疑上面有一些小错误,但这个概念应该是可行的。