tags:

views:

237

answers:

8

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.

A: 

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.

Reed Copsey
Yes, there is a difference in the generated IL. Using `base` causes the `call` instruction to be used instead of `callvirt`.
Greg Beech
Only in an overridden function, though. If the function is not virtual, it still uses call without the base.
Reed Copsey
That was one of my specific cases where I mentioned it does matter, and why I specified "in most cases"
Reed Copsey
+1  A: 

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
   }
}
Mehrdad Afshari
Also potentially required if you're using "new" to hide the base class method.
Reed Copsey
Yeah. In that case, it would make the same difference. There's an alternate way of calling a `new` method using `((Base)obj).Method()`.
Mehrdad Afshari
+13  A: 

The base keyword is important when overriding methods:

override void Foo()
{
  base.Foo();
  // other stuff
}

I never use it for anything else.

Stefan Steinegger
If you have a "new" method in your class, with the same name, it's also potentially required.
Reed Copsey
When you use `new` to shadow a method, you also have an option of casting `this` to base class type and calling the method on that (granted it's longer than `base`, so why would you do that? but it is a possibility nonetheless). The case with `override` is the only case where you _must_ use `base`, with no other option.
Pavel Minaev
But the question wasn't "do you HAVE to use base...", but rather "should you use base....". I personally think its more clear to use base than cast + call.
Reed Copsey
I would actually also use base instead of a cast when "newing" a method. I forgot about this case, a rarely use "new". I just mean that I never use base to call methods of the base class in general. When calling a method, I should not care where it is actually implemented, this is the nature of polymorphism.
Stefan Steinegger
There were some really good points made in serveral answers to my question. I should have mentioned overriding methods in my question, I was thinking more of readability when I asked it but now am more aware of the finer points of using the base keyword. May thanks to all the respondents.
DaveB
A: 

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.

Michael Burr
+1  A: 

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.

Adam Wright
A: 

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()

DreamWalker
+1  A: 

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.

Pavel Minaev
+8  A: 

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.

Greg Beech
+1 - This is a nice, precise answer. As one additional note, an inherited function should be thought of as a member of the inheriting class; it is not only a member of the base class anymore. So calling this.Foo() (where Foo is inherited) is very valid, and as Greg says, you almost always want that syntax.
Walt W
Not strictly true. As Reed pointed out, callvirt is only used if the base class has a virtual Foo. In all other cases there is no difference.
PaulG
@PaulG - True, but that doesn't affect what you're saying semantically. By using `base` you're still saying that you specifically want the base implementation. Do you really want callers to have to check each method to see if it's virtual to know the intent? And what if a method changes to be virtual during refactoring; do you want to visit all the call sites to see if your assumption still holds?
Greg Beech
+1 Good answer.
Repo Man