Overwrite methods based on name only

I'm creating an abstract base class to provide a pattern for other classes.

Methods of the base class must be overwritten in the derived class.

Now comes the cat jump. Overwriting should happen only based on the name of the method, without taking into account the parameters.

Example:

public abstrac class A
{
    public int AnyMethod()
    {
        throw new NotImplementedException ( "This method is not implemented" );
    }
}

public class B : A
{
    public override int AnyMethod( int a, int b)
    {
        return a + b;
    }
}

As you can see, my idea is to overwrite a method of the base class independent of the parameters, that is, only based on the name of the method.

Is this possible?

Author: Maniero, 2016-07-10

2 answers

No, this is not possible, the method is not composed only by its name. Whenever the method signature is different it is another method. There is method overload (which is quite common, more than operator overload). The very example placed there shows that no, since it does not have override.

Of course there are ways to achieve a similar goal by going over language if it was something really necessary, but if it is to do this it is better to use another language, than creating a sophisticated mechanism to circumvent what the language purposely prevents.

To tell the truth you shouldn't even use inheritance if you want the method to have different parameters, because in practice they do different things, so inheritance, or at least polymorphism, is the wrong mechanism.

What you can do, depending on the case, is to use a public method with equal signature for the inheritance and have private methods to have a more appropriate implementation in each class, then the inherited public method would call the private one with different signature. Or one can think of some other mechanism that uses something similar.

I would say that everyone would be gambiarras to circumvent the philosophy of language. I just do not make a categorical statement because I do not know the concrete case. In some very specific case it is possible that such a solution can be used without problems. In this example demonstrated it does not seem appropriate because the method is making a sum of two operands.

Note that using another signature, such as params, is doing something different than what the question asks, i.e. the signature has been changed so that override occurs based on the whole and not just the name. There is a difference between parameters and arguments .

The use of the modifier new, which does not overwrite , does not have the least serventia for this problem since it would only hide the base method that has the same signature, in a different signature method its use is unnecessary and the operation is exactly the same without the modifier, after all this is a new method by definition.

Throwing a NotImplementedException is rarely a good idea, it is certainly not in a method that serves as a basis.

I ignored small errors that maybe exist only in the example, obviously they will not be committed in the concrete case, nor would I compile.

 5
Author: Maniero, 2020-02-06 14:52:00

In this case, we will have to be creative. Simply ignoring the arguments extrapolates the design of the C # language.

First, the method, to be overwritten, needs to be virtual:

public virtual int AnyMethod()
{
    throw new NotImplementedException ( "This method is not implemented" );
}

Second, it is possible to make an implementation that receives N arguments of a given type. Or, still, of object, but this if you like to live with emotion:

public virtual int AnyMethod(params int[] numeros)
{
    throw new NotImplementedException ( "This method is not implemented" );
}

Third, you can instead derive polymorphisms with different arguments in the derived class. Somewhat like this:

public class B: A
{
    public override int AnyMethod(params int[] lista)
    {
        return lista.Sum(x => x);
    }

    public int AnyMethod(int a, int b) 
    {
        return AnyMethod(new int[] {a, b});
    }
}

Then we can have a specific method with 2 arguments and another with N.

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new B().AnyMethod(1, 2));
        Console.WriteLine(new B().AnyMethod(1, 2, 3));
    }
}

I made a Fiddle for you .


At the request of the questioner, I will also explain one more option, which is the reintroduction of methods, made by the modifier word new in the method.

new it would be the equivalent of Delphi's reintroduce, in which we explicitly overwrite a method of the base class in the derived class. The difference for override is that the method of the base class is can be called using base.AnyMethod, while using new the method of the base class is totally ignored.

In the scope of the example, if there was a method public int AnyMethod(int a, int b) in the base class, it would be something like:

public new int AnyMethod(int a, int b) 
{
    return a + b;
}

This type of operator, as well as the addition of more polymorphisms in derived classes, can be prevented by using the modifier sealed in the class declaration.

I updated the Fiddle by now putting a polymorphism for three operators.

 2
Author: Leonel Sanches da Silva, 2016-07-11 15:28:54