Reputation: 9530
When calling methods on a base class from a derived class, should the 'base' keyword be used? It seems using the base keyword would increase code readability but for me so far, when I exclude it, there is no affect on code compilation and execution.
Upvotes: 4
Views: 879
Reputation: 136577
You should not use base
unless you specifically mean "Even if there is a method in this class that overrides the base implementation, I want to call the base implementation and ignore the one on this class".
Using base
bypasses the virtual dispatch mechanism that is so important in polymorphism by causing a call
instruction to be emitted rather than callvirt
.
So saying base.Foo()
is very, very different in semantics to saying this.Foo()
. And you almost always want the latter.
Upvotes: 10
Reputation: 101555
I'd say no. The main purpose of base
is to allow you to call base class versions of virtual methods without virtual dispatch taking place. Personally, I consider any other use of base
to be an abuse - it doesn't really buy you anything over just calling a method as usual (or using this
), and it will break if you later override the called method in your class.
Also, there is a very real difference if the method is virtual, and someone down the line overrides it. To give an example, say you write this (in a reusable class):
class Base {
public virtual void Foo() {}
}
class Derived : Base {
void Bar() { base.Foo(); }
}
And later on someone else who uses your class writes:
class MoreDerived : Derived {
public override void Foo() {}
}
Now your base.Foo()
will not do dynamic dispatch, and therefore will not call the overridden Foo()
in MoreDerived
. It may be what you actually want, but I'd find such a code very suspect if that was the intent.
Upvotes: 1
Reputation: 19011
Look to this example:
class ParentClass {
public virtual void A() {
// Some operations
}
}
class ChildClass : ParentClass {
public override void A()
{
base.A();
}
}
If we execute ChildClass.A() then we have some operations, but in this case:
class ParentClass {
public virtual void A() {
Console.WriteLine("ParentClass.A");
}
}
class ChildClass : ParentClass {
public override void A()
{
A();
}
}
we have StackOverflowException, because ChildClass.A() execute ChildClass.A()
Upvotes: 0
Reputation: 564363
There will be no difference in the generated IL in most cases.
However, if you are overriding a virtual method in the base class, or hiding a method in the base class using the "new" keyword, then this is required, and will change the meaning, since it explicitly calls the base class method.
However, it is often a good idea, since it improves readability, and hence maintainability. If you are explicitly wanting to call a method in the base class, then I feel that it's a good idea, even when not technically required.
Upvotes: -1
Reputation: 49376
Sometimes, you can't avoid it. If your class overrides an implementation of a function from the base class, then without the base
keyword, calls could be dispatched to the implementation in your class.
In all other situations, it's a matter of style (much like "Should I prefix all calls/field accesses with this
). I say "No" as it tends to increase code clutter without significantly helping readability, but "Yes" is just as valid an answer - especially if you have a class with many overridden methods, but will be including many calls upwards in the hierarchy.
Upvotes: 1
Reputation: 340178
There are times when the base keyword has to be used such when you want to call a method in the base class that's been overidden in the derived class.
Upvotes: 0
Reputation: 64628
The base keyword is important when overriding methods:
override void Foo()
{
base.Foo();
// other stuff
}
I never use it for anything else.
Upvotes: 13
Reputation: 421978
It does matter if you have overridden
a method:
class Test {
public override string ToString() { return "Hello World"; }
public string M1() { return ToString(); } // Test.ToString
public string M2() { return base.ToString(); } // System.Object.ToString
static void Main() {
var t = new Test();
Console.WriteLine("M1: {0}", M1()); // Hello World
Console.WriteLine("M2: {0}", M2()); // Test
}
}
Upvotes: 1