简体   繁体   English

C#:重写抽象方法的更好方法,在该方法中,被重写的方法将忽略其某些参数

[英]C#: Better way to override an abstract method in which the overridden method ignores some of its arguments

So, I have an abstract class with a method with 3 parameters, which is overridden in a particular base class. 因此,我有一个带有3个参数的方法的抽象类,该类在特定的基类中被覆盖。

The abstract method is in the following form: 抽象方法的格式如下:

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

In most of the subclasses that implement the given method, all 3 parameters are needed to produce a correct result. 在实现给定方法的大多数子类中,需要三个参数才能产生正确的结果。 However, in this particular instance the only valid values of a and b are 0. 但是,在此特定情况下,a和b的唯一有效值为0。

Currently what I am doing is just ignoring their values within the method, and providing a warning in the documentation comment for the method, but this just feels...wrong. 目前,我正在做的只是忽略方法中的它们的值,并在该方法的文档注释中提供警告,但这感觉...不对。

There has to be a better way than forcing a programmer (well, me) to insert junk arguments into the method call just to make the compiler happy, while still requiring the use of these arguments for every other subclass that implements the method. 有一种比强迫程序员(好吧,我)将垃圾参数插入方法调用中来使编译器满意的更好的方法,同时仍然要求对实现该方法的每个其他子类使用这些参数。

Maybe this is a dumb question, since my solution works, but it just feels like it's not a smart way to do it. 既然我的解决方案有效,也许这是一个愚蠢的问题,但这只是感觉这不是一个明智的方法。 For example, some idiot (probably me) shouldn't be able to come along and cause an unhandled exception by inserting some ridiculous number into an argument that isn't used in the first place. 例如,某些白痴(可能是我)应该无法通过将一些荒谬的数字插入最初没有使用的参数中而导致未处理的异常。

Another option (given that you mentioned the parameters are really coordinates that may or may not be used) could be just to make the values nullable with default values of null. 另一个选择(假设您提到的参数实际上是可能使用或可能不使用的坐标)可能只是使这些值可为空且默认值为null。

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

You'd have to match the abstract definition as well, but this shows the approach. 您还必须匹配抽象定义,但这显示了该方法。

This allows the sub-classes to call SummonJonSkeet("my question") or SummonJonSkeet("my question", 1, 2) based on its implementation. 这允许子类根据其实现调用SummonJonSkeet("my question")SummonJonSkeet("my question", 1, 2) The sub-classes that expect the values can then check a.HasValue or a != null to throw errors when values does not exist for parameters when expected to have values. 然后,期望值的子类可以检查a.HasValuea != null以在期望具有值的参数不存在值时引发错误。 To get the primitive value, just call a.Value . 要获取原始值,只需调用a.Value

You might consider an approach that creates a class for the parameters (assuming you might need these parameters to have specific names or various types). 您可能会考虑为参数创建类的方法(假设您可能需要这些参数具有特定的名称或各种类型)。

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

Then, you could modify your abstract class to be generic that requires a type that is of the type BasicQuestionParameters. 然后,您可以将抽象类修改为通用类型,该通用类需要类型为BasicQuestionParameters的类型。

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

Now you can implement your sub-classes to define what type of question parameters it needs as long as they start from your basic one. 现在,您可以实现子类,以定义所需的问题参数类型,只要它们从您的基本参数开始即可。

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

The benefit here is now you can add additional parameters by inheritance: 现在的好处是,您可以通过继承添加其他参数:

public class HardQuestionParameters : BasicQuestionParameters
{
    public int A {get;set;}
    public int B {get;set;}
}

And then use this in only the sub-classes that need the more refined type: 然后仅在需要更精细类型的子类中使用它:

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

Now each sub-class has exactly the parameters it needs and nothing more or less. 现在,每个子类都具有所需的确切参数,仅此而已。 This approach has the added benefit that if you find a set of sub-classes need an additional parameter (C), you can do it by only needing to update the sub-classes that need to use the additional parameter. 这种方法的附加好处是,如果发现一组子类需要附加参数(C),则只需更新需要使用附加参数的子类即可。 No need to touch all the other sub-classes that just need the basic parameters. 无需触摸仅需要基本参数的所有其他子类。

If you do not use the int parameters, you can change the signature of the virtual method to: 如果不使用int参数,则可以将虚拟方法的签名更改为:

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

In this way you can call it with only the string parameter, like this: 这样,您可以仅使用string参数来调用它,如下所示:

this.SummonJonSkeet(dumbQuestion);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM