简体   繁体   中英

C# virtual methods override the return type & method arguments

I want to init virtual method with exact name in abstract class.

And in class, which is the inheritor override method such, that I can override:

  • the return type of the base method
  • arguments of the method

To show you, what I'm really want to do is smth like this:

abstract class A
{
    public virtual void Func1() { }
}

class B : A
{
    override string Func1(int a, int b)
    {
         return (a + b).ToString();
    }
}

I know, that C# requires to use the return type/args as in base class, but maybe there are some hints with keyword new in this situation?

You can only override the exact name and arguments. You can new whatever you want, but that's not overriding--just hiding in the case of an exact match.

I think in your situation you will either want to create overloads for all possible combinations, or create a single base, abstract method which takes a single type that can contain the arguments you want.

Example:

public abstract void Func1( MyArgumentsType input );

Now derived classes are compelled to override a method but you can pass a robust set of arguments to the method that can handle more scenarios.

Polymorphism works to your advantage here, as you can then pass derived argument types to the method with situation-specific properties. Of course, this requires the implementing method to understand the more derived argument type.

Your cant'd do this. Overriding a method requires to have the exact same signature, which includes parameters and return type. There is no way for you to tell a compiler to override a method with different parameters and return type.

If you want polymorphic behavior, you need to have compatible signatures. Otherwise compiler can't guarantee, that the required method will be found polymorphically.

There is no concivable way to treat signatures void Func1() and string Func1(int a, int b) as polymorphic. You can generalize them with out parameters of pass lambdas inside, but anyway - to take advantage of polymorphic behavior you need to bring them to one common signature.

Method overriding means modifying the virtual implementation of an inherited member and not it's signature . As you pointed out the new keyword will hide the base class's implementation of the member with the same name. However it is only optional, take a look at this
benefit of using new keyword in derived class member having same name with base class member

It looks like you want to achieve behavior similar to ToString method that have many different flavors for different types (like .ToString() and float.ToString("c") ).

In this case different implementations of ToString are not implementations of Object.ToString but rather normal additional method on derived objects that resolved appropriately based on arguments. All derived classes endup with one virtual ToString method (coming from base class and potentially implemented in current class) and optionally other similarly named methods that are not virtual.

Note that in C# result type newer taken into account in function resolution time, so you can't really have 2 functions with the same name and same arguments and expect one to be "correctly" picked. If both are visible at the same time you'll get compile time error. new keyword in front of method makes only that method visible for that class (and derived ones) and hiding base class method with the same signature. Unfortunately doing so pretty much guarantees a lot of confusion when one uses variable of base class holding derived class to call this method - the virtual one from base class will be called despite all efforts to hid one.

Think about it...how will it work? Say you have an reference whose static type is A but dynamic type is B , as follows:

foo(B b) { bar(b); }
bar(A a) { 
}

The idea behind overriding is that you call a method on super/base and it resolves to the overridden implementation. By that logic you should be able to, in bar , call a.Func1() and it should call the method in B :

a.Func1(???)

But that is not possible here, because of missing parameters.

There are notions of parameter contravariance and return type covariance; here is an interesting answer in SO, with a link to a post by Eric Lippert that should be an interesting read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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