views:

738

answers:

9

What 's the practical usage of virtual functions in c#?

A: 

From here:

In object-oriented programming, a virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature.

Burkhard
+4  A: 

Like any other language..when you want polymorphism. There are tons of usage for this. For example you want to abstract the way input is read from a console or a file or some other device. You can have a generic reader interface followed by multiple concrete implementations using virtual functions.

Naveen
+1  A: 

e.g. proxying methods. i.e. overwriting methods at runtime. For example, NHibernate uses this to support lazy loading.

Joachim Kerschbaumer
A: 

For example you have a base class Params and a set of derived classes. You want to be able to perform the same operation on an array that stores all possible classes derived from params.

No problem - declare the method virtual, add some basic implementation to Params class and override it in derived classes. Now you can just traverse the array and call the method through the reference - the correct method will be called.

class Params {
public:
   virtual void Manipulate() { //basic impl here }
}

class DerivedParams1 : public Params {
public:
   override void Manipulate() {
      base.Manipulate();
      // other statements here
   }
};

// more derived classes can do the same

void ManipulateAll( Params[] params )
{
    for( int i = 0; i < params.Length; i++ ) {
       params[i].Manipulate();
    }
 }
sharptooth
+1  A: 

It's used to tell a derived class that the function can be overridden.

MSDN has a good example here.

Gerrie Schenck
+1  A: 

Basically virtual members allow you to express polymorphism, a derived class can have a method with the same signature as the method in its base class, and the base class will call the derived class's method.

A basic example:

public class Shape
{
    // A few example members
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }

    // Virtual method
    public virtual void Draw()
    {
        Console.WriteLine("Performing base class drawing tasks");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        // Code to draw a circle...
        Console.WriteLine("Drawing a circle");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        // Code to draw a rectangle...
        Console.WriteLine("Drawing a rectangle");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        // Code to draw a triangle...
        Console.WriteLine("Drawing a triangle");
        base.Draw();
    }
}
CMS
"and the base class will call the derived class's method." that is a pretty confusing statement paired with the sample code; the text indicates that base.Draw will cause the derived classes Draw method to be invoked (which would result in an StackOverflowException, I think). I get your point, but a newcomer might not. The sample code as such is really good though; running it will clearly show what happens.
Fredrik Mörk
+6  A: 

So basically if in your ancestor class you want a certain behaviour for a method. If your descendent uses the same method but has a different implementation you can override it, If it has a virtual keyword.

using System;
class TestClass 
{
   public class Dimensions 
   {
      public const double pi = Math.PI;
      protected double x, y;
      public Dimensions() 
      {
      }
      public Dimensions (double x, double y) 
      {
         this.x = x;
         this.y = y;
      }

      public virtual double Area() 
      {
         return x*y;
      }
   }

   public class Circle: Dimensions 
   {
      public Circle(double r): base(r, 0) 
      {
      }

      public override double Area() 
      { 
         return pi * x * x; 
      }
   }

   class Sphere: Dimensions 
   {
      public Sphere(double r): base(r, 0) 
      {
      }

      public override double Area()
      {
         return 4 * pi * x * x; 
      }
   }

   class Cylinder: Dimensions 
   {
      public Cylinder(double r, double h): base(r, h) 
      {
      }

      public override double Area() 
      {
         return 2*pi*x*x + 2*pi*x*y; 
      }
   }

   public static void Main()  
   {
      double r = 3.0, h = 5.0;
      Dimensions c = new Circle(r);
      Dimensions s = new Sphere(r);
      Dimensions l = new Cylinder(r, h);
      // Display results:
      Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
      Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
      Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
   }
}

Edit: Questions in comment
If I don't use virtual keyword in base class, will it work?

If you use the override keyword in your descendent classes it will not work. You will generate compiler error CS0506 'function1' : cannot override inherited member 'function2' because it is not marked "virtual", "abstract", or "override"

If you don't use the override You'll get the CS0108 warning 'desc.Method()' hides inherited member 'base.Method()' Use the new keyword if hiding was intended.

To get around this put the new keyword in front of the method you are hiding.

e.g.

  new public double Area() 
  {
     return 2*pi*x*x + 2*pi*x*y; 
  }

..and is it compulsory to override a virtual method in derived class?
No, if you don't override the method, the descendent class will use method it is inheriting from.

John Nolan
what if i don't use virtual keyword in base class? will it work? and is it compulsary to override virtual method in derivered class ?
Preeti Singh
@Pre I've answered your questions in the comments
John Nolan
thanks John.now it's clear.
Preeti Singh
A: 

This allows to achieve late binding, meaning to determine at runtime rather than at compile-time which object's member will be invoked. See Wikipedia.

Juri