c#:重写抽象方法的更好方法,其中被重写的方法忽略了它的一些参数

本文关键字:方法 重写 参数 抽象方法 更好 | 更新日期: 2023-09-27 18:08:03

所以,我有一个抽象类,它有一个带有3个参数的方法,它在一个特定的基类中被覆盖。

抽象方法的形式如下:

internal override void SummonJonSkeet(string dumbQuestion, int a, int b)
{
    // Call upon Jon Skeet and his followers to correct my ignorant ways. 
}

在大多数实现给定方法的子类中,需要所有3个参数才能产生正确的结果。然而,在这个特殊的实例中,a和b的唯一有效值是0。

目前我所做的只是在方法中忽略它们的值,并在该方法的文档注释中提供警告,但这只是感觉…不对。

必须有一个更好的方法,而不是强迫程序员(好吧,是我)在方法调用中插入垃圾参数,只是为了让编译器高兴,同时仍然要求对实现该方法的每个其他子类使用这些参数。

也许这是一个愚蠢的问题,因为我的解决方案有效,但感觉这不是一个聪明的方法。例如,某些白痴(可能是我)不应该通过在一开始就没有使用的参数中插入一些荒谬的数字而导致未处理的异常。

c#:重写抽象方法的更好方法,其中被重写的方法忽略了它的一些参数

另一个选项(考虑到您提到的参数实际上是可能使用也可能不使用的坐标)可能只是使值为空,默认值为null。

internal override void SummonJonSkeet(string dumbQuestion, int? a = null, int? b = null)

您也必须匹配抽象定义,但这显示了方法。

这允许子类根据其实现调用SummonJonSkeet("my question")SummonJonSkeet("my question", 1, 2)。期望这些值的子类可以检查a.HasValuea != null,当期望有值的参数值不存在时抛出错误。要获取原始值,只需调用a.Value

您可以考虑为参数创建一个类的方法(假设您可能需要这些参数具有特定的名称或各种类型)。

public class BasicQuestionParameters { public string DumbQuestion {get;set;} }

然后,您可以将抽象类修改为泛型,它需要一个类型为BasicQuestionParameters的类型。

public abstract class SummonBase<TParams> where TParams : BasicQuestionParameters
{
     abstract void SummonJobSkeet(TParams question);
}

现在你可以实现你的子类来定义它需要什么类型的问题参数,只要它们从你的基本参数开始。

public class MySummonBasic : SummonBase<BasicQuestionParameters>
{
    internal override void SummonJonSkeet(BasicQuestionParameters question) {...}
}
这里的好处是现在您可以通过继承添加额外的参数:
public class HardQuestionParameters : BasicQuestionParameters
{
    public int A {get;set;}
    public int B {get;set;}
}

然后只在需要更精细类型的子类中使用:

public class HardSummon : SummonBase<HardQuestionParameters>
{
     internal override void SummonJonSkeet(HardQuestionParameters question) {...}
}

现在每个子类都有它所需要的参数,不多不少。这种方法还有一个额外的好处,如果您发现一组子类需要额外的参数(C),您只需更新需要使用额外参数的子类即可。

如果不使用int形参,可以将虚方法的签名修改为:

internal override void SummonJonSkeet(string dumbQuestion, params int[] values)
{
    //...
}

通过这种方式,您可以只使用string形参调用它,如下所示:

this.SummonJonSkeet(dumbQuestion);