Override methods based on name only

3

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

Base class methods must be overridden in the derived class.

Now comes the cat's leap. The override should only happen based on the method name, regardless of 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 override a method of the base class independent of the parameters, that is, based only on the method name.

Is this possible?

    
asked by anonymous 10.07.2016 / 19:23

2 answers

4

Responding directly to the question about inheritance and polymorphism: no, this is not possible, the method is not only composed by your name . Whenever the method signature is different, it is another method. Contrary to what the other answer says there is no polymorphism between different methods, there is method overload (which is pretty common, over that operator overhead), and that is different from what the question asks. The example put there shows that no, since it does not have override .

Of course you have ways to achieve a similar goal by going over language if it were something really necessary, but if it is to do so, it is better to use another language, than to create a sophisticated mechanism to circumvent what language purposely prevents .

To tell you the truth, you should not use inheritance if you want the method to have different parameters, because in practice they do different things , then 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 to have private methods to have a more appropriate implementation in each class, then the public inherited method would call the private one with a different signature. Or you can think of some other mechanism that uses something similar.

I would say that all 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 some solution can be used without problems. In this example shown 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 other than what the query asks, ie the signature has been changed so that override occurs based on the whole, not just the name. There is a difference between parameters and arguments .

Using modifier new , which does not overwrite , has no use for this problem since it only hid 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.

Casting a NotImplementedException is rarely a good idea, it's certainly not a baseline method.

I ignored small mistakes that may only exist in the example, obviously they will not be committed in the concrete case, nor compiled.

    
10.07.2016 / 19:30
2

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

First, the method, to be overwritten, must 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 even 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. Something 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 you a Fiddle .

At the request of the question's author, I'll also explain one more option, which is reintroducing methods, made by the modifier word new in method .

new would be the equivalent of reintroduce of Delphi, in which we explicitly override a base-class method in the derived class. The difference to override is that the method of the base class is can be called using base.AnyMethod , whereas using new the method of the base class is totally ignored.

In the example scope, if there was a public int AnyMethod(int a, int b) method in the base class, it would look 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 using modifier sealed "in the class declaration.

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

    
10.07.2016 / 19:42