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.
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.
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.
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.
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.
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.
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.
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.
0 commentaires:
Enregistrer un commentaire