Skip to footer content
.NET HELP

C# Virtual Keyword (How It Works For Developers)

In C#, the virtual keyword is a pivotal concept in object-oriented programming that facilitates polymorphism, allowing developers to override methods in derived classes. This keyword, when applied to a class method, property, or event, indicates that the entity can have its behavior modified by a derived class using the override keyword. In this tutorial, we'll learn about the C# Virtual Keyword and explore the IronPDF library. Let's dive straight into how it works and see it in action with practical examples.

Virtual Methods in Action

Basic Usage of Virtual Keyword

At its core, a virtual method is a base class method that allows derived classes to provide a specific implementation for methods that are already defined in the base class.

The virtual keyword in C# marks a method, property, or event as virtual, signaling that it can be overridden in any class inheriting from it. Consider the following example where we define a base class Shape with a virtual method Area:

public class Shape
{
    public virtual double Area()
    {
        return 0; // Default implementation, returns 0
    }
}
public class Shape
{
    public virtual double Area()
    {
        return 0; // Default implementation, returns 0
    }
}
Public Class Shape
	Public Overridable Function Area() As Double
		Return 0 ' Default implementation, returns 0
	End Function
End Class
$vbLabelText   $csharpLabel

Overriding Virtual Methods

Derived classes can override these virtual methods to provide their own implementation, tailored to the specific requirements of the derived class. Using the override keyword, let's create a Circle class that derives from Shape and provides its own version of the Area method:

public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double Area()
    {
        // Own implementation for circle area
        return Math.PI * Radius * Radius; 
    }
}
public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double Area()
    {
        // Own implementation for circle area
        return Math.PI * Radius * Radius; 
    }
}
Public Class Circle
	Inherits Shape

	Public Property Radius() As Double

	Public Sub New(ByVal radius As Double)
		Me.Radius = radius
	End Sub

	Public Overrides Function Area() As Double
		' Own implementation for circle area
		Return Math.PI * Radius * Radius
	End Function
End Class
$vbLabelText   $csharpLabel

In the above code, the Circle class provides its specific implementation of the Area method, which calculates the area of a circle. This demonstrates the power of virtual methods in polymorphism.

Non-Virtual Methods

It's important to note that not all methods need to be or should be virtual. A non-virtual method is defined in such a way that it cannot be overridden in derived classes, which means the initial implementation remains unchanged and is utilized by all classes that inherit from it. This is useful when a base class provides a standard implementation that should not be altered.

Practical Application

Let's put these concepts to work in a practical scenario. Consider the following program that uses our Shape and Circle classes:

public class Program
{
    public static void Main(string[] args)
    {
        Shape myShape = new Shape();
        Shape myCircle = new Circle(5);

        // Display the area calculation of the default and overridden methods.
        Console.WriteLine($"Shape area: {myShape.Area()}");
        Console.WriteLine($"Circle area: {myCircle.Area()}");
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        Shape myShape = new Shape();
        Shape myCircle = new Circle(5);

        // Display the area calculation of the default and overridden methods.
        Console.WriteLine($"Shape area: {myShape.Area()}");
        Console.WriteLine($"Circle area: {myCircle.Area()}");
    }
}
Public Class Program
	Public Shared Sub Main(ByVal args() As String)
		Dim myShape As New Shape()
		Dim myCircle As Shape = New Circle(5)

		' Display the area calculation of the default and overridden methods.
		Console.WriteLine($"Shape area: {myShape.Area()}")
		Console.WriteLine($"Circle area: {myCircle.Area()}")
	End Sub
End Class
$vbLabelText   $csharpLabel

The above example program demonstrates polymorphism in action and the essence of virtual function. Despite myCircle being declared as a Shape, it calls the overridden Area method from the Circle class, showcasing the dynamic dispatch mechanism facilitated by the virtual and override keywords.

C# Virtual Keyword (How It Works For Developers): Figure 1 - Console output from the code above showcasing how myCircle calls the overridden Area method

Advanced Uses of Virtual and Override Keywords

Abstract Methods and Classes

Abstract methods are a step further, used in abstract classes. An abstract method is a method declared in the base class without an implementation and must be overridden in derived classes. It forces derived classes to provide an implementation for the abstract method, ensuring a consistent interface while allowing for customized behavior in each derived class.

Method Overloading vs. Overriding

It's also crucial to understand the difference between method overloading and method overriding. Method overloading occurs within the same class and allows more than one method to have the same name but different parameters. Method overriding, facilitated by virtual and override keywords, allows a derived class to provide a different implementation for a method defined in the base class.

Virtual Properties and Events

Besides methods, properties, and events can also be virtual. This enables derived classes to provide custom getters, setters, and event handlers, further enhancing the flexibility of class hierarchies.

IronPDF: .NET PDF Library

IronPDF is a comprehensive library designed for C# developers to generate, manipulate, and render PDF documents directly within .NET applications. It offers an intuitive API that simplifies working with PDF files, such as using HTML to create a PDF, helping developers to create, edit, and convert PDFs without needing to understand the complex underlying PDF document structure or resort to external software. IronPDF seamlessly integrates with the language's object-oriented features, including the use of the virtual keyword, to provide customizable PDF processing capabilities.

Using the virtual keyword with IronPDF allows developers to extend the functionality of IronPDF's classes within their applications. By defining base classes with virtual methods related to PDF generation or manipulation, developers can create derived classes that override these methods to tailor the PDF processing behavior to specific needs.

Example: Customizing PDF Rendering with Virtual Methods

Imagine you have a base class that uses IronPDF to render PDFs from HTML strings. By marking the rendering method as virtual, you allow derived classes to modify or enhance the rendering process. Here's a simple example:

public class BasicPdfRenderer
{
    // Virtual method allowing customization in derived classes
    public virtual byte[] RenderHtmlToPdf(string htmlContent)
    {
        // Use IronPDF to render PDF from HTML
        var renderer = new IronPdf.ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
        return pdfDocument.BinaryData;
    }
}

public class CustomPdfRenderer : BasicPdfRenderer
{
    // Overriding the base class method to implement custom rendering settings
    public override byte[] RenderHtmlToPdf(string htmlContent)
    {
        var renderer = new IronPdf.ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);

        // Apply a prominent watermark to the PDF document
        pdfDocument.ApplyWatermark("<h2 style='color:red; font-size: 60px; opacity: 0.5; text-shadow: 2px 2px 5px grey;'>SAMPLE</h2>",
                                   30,
                                   IronPdf.Editing.VerticalAlignment.Middle,
                                   IronPdf.Editing.HorizontalAlignment.Center);

        // Return the binary data of the PDF document
        return pdfDocument.BinaryData;
    }
}

class Program
{
    static void Main(string[] args)
    {
        License.LicenseKey = "License-Key";

        // HTML content to be converted to PDF
        string htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a simple PDF document generated from HTML.</p>";

        // Create an instance of CustomPdfRenderer
        CustomPdfRenderer renderer = new CustomPdfRenderer();

        // Call RenderHtmlToPdf method to generate PDF binary data
        byte[] pdfData = renderer.RenderHtmlToPdf(htmlContent);

        // Specify the file path to save the PDF
        string filePath = "f:\\CustomRenderedPdf.pdf";

        // Save the binary data to a file
        File.WriteAllBytes(filePath, pdfData);

        // Output success message
        Console.WriteLine($"PDF generated and saved to {filePath}");
    }
}
public class BasicPdfRenderer
{
    // Virtual method allowing customization in derived classes
    public virtual byte[] RenderHtmlToPdf(string htmlContent)
    {
        // Use IronPDF to render PDF from HTML
        var renderer = new IronPdf.ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
        return pdfDocument.BinaryData;
    }
}

public class CustomPdfRenderer : BasicPdfRenderer
{
    // Overriding the base class method to implement custom rendering settings
    public override byte[] RenderHtmlToPdf(string htmlContent)
    {
        var renderer = new IronPdf.ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);

        // Apply a prominent watermark to the PDF document
        pdfDocument.ApplyWatermark("<h2 style='color:red; font-size: 60px; opacity: 0.5; text-shadow: 2px 2px 5px grey;'>SAMPLE</h2>",
                                   30,
                                   IronPdf.Editing.VerticalAlignment.Middle,
                                   IronPdf.Editing.HorizontalAlignment.Center);

        // Return the binary data of the PDF document
        return pdfDocument.BinaryData;
    }
}

class Program
{
    static void Main(string[] args)
    {
        License.LicenseKey = "License-Key";

        // HTML content to be converted to PDF
        string htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a simple PDF document generated from HTML.</p>";

        // Create an instance of CustomPdfRenderer
        CustomPdfRenderer renderer = new CustomPdfRenderer();

        // Call RenderHtmlToPdf method to generate PDF binary data
        byte[] pdfData = renderer.RenderHtmlToPdf(htmlContent);

        // Specify the file path to save the PDF
        string filePath = "f:\\CustomRenderedPdf.pdf";

        // Save the binary data to a file
        File.WriteAllBytes(filePath, pdfData);

        // Output success message
        Console.WriteLine($"PDF generated and saved to {filePath}");
    }
}
Public Class BasicPdfRenderer
	' Virtual method allowing customization in derived classes
	Public Overridable Function RenderHtmlToPdf(ByVal htmlContent As String) As Byte()
		' Use IronPDF to render PDF from HTML
		Dim renderer = New IronPdf.ChromePdfRenderer()
		Dim pdfDocument = renderer.RenderHtmlAsPdf(htmlContent)
		Return pdfDocument.BinaryData
	End Function
End Class

Public Class CustomPdfRenderer
	Inherits BasicPdfRenderer

	' Overriding the base class method to implement custom rendering settings
	Public Overrides Function RenderHtmlToPdf(ByVal htmlContent As String) As Byte()
		Dim renderer = New IronPdf.ChromePdfRenderer()
		Dim pdfDocument = renderer.RenderHtmlAsPdf(htmlContent)

		' Apply a prominent watermark to the PDF document
		pdfDocument.ApplyWatermark("<h2 style='color:red; font-size: 60px; opacity: 0.5; text-shadow: 2px 2px 5px grey;'>SAMPLE</h2>", 30, IronPdf.Editing.VerticalAlignment.Middle, IronPdf.Editing.HorizontalAlignment.Center)

		' Return the binary data of the PDF document
		Return pdfDocument.BinaryData
	End Function
End Class

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key"

		' HTML content to be converted to PDF
		Dim htmlContent As String = "<h1>Hello, IronPDF!</h1><p>This is a simple PDF document generated from HTML.</p>"

		' Create an instance of CustomPdfRenderer
		Dim renderer As New CustomPdfRenderer()

		' Call RenderHtmlToPdf method to generate PDF binary data
		Dim pdfData() As Byte = renderer.RenderHtmlToPdf(htmlContent)

		' Specify the file path to save the PDF
		Dim filePath As String = "f:\CustomRenderedPdf.pdf"

		' Save the binary data to a file
		File.WriteAllBytes(filePath, pdfData)

		' Output success message
		Console.WriteLine($"PDF generated and saved to {filePath}")
	End Sub
End Class
$vbLabelText   $csharpLabel

We utilize IronPDF within a BasicPdfRenderer class to convert HTML to PDF, marking its RenderHtmlToPdf method as virtual to allow customization. The CustomPdfRenderer class, derived from BasicPdfRenderer, overrides this method to not only perform the conversion but also to inject a distinct, large, red watermark across the generated PDF.

Output PDF File

It is the PDF file generated by the IronPDF:

C# Virtual Keyword (How It Works For Developers): Figure 2 - Example code output utilizing the virtual method RenderHtmlToPDF from CustomPdfRendered for conversion

Conclusion

C# Virtual Keyword (How It Works For Developers): Figure 3 - Learn about IronPDF's licensing process

The virtual keyword in C# is a cornerstone of object-oriented programming, enabling polymorphism and dynamic dispatch. By allowing derived classes to provide specific implementations of methods, properties, and events defined in base classes, it empowers developers to create flexible and reusable code structures. Through practical examples and understanding the relationship between virtual methods, override mechanisms and class hierarchies, developers can effectively utilize these concepts in building robust applications. Furthermore, these concepts would also help developers to use IronPDF more efficiently in their applications. You can test IronPDF without spending anything using its free trial options.

Frequently Asked Questions

What is the purpose of the virtual keyword in C#?

The virtual keyword in C# is used to mark a method, property, or event as virtual, which means it can be overridden in any class that inherits from it. This is a cornerstone concept in object-oriented programming that facilitates polymorphism.

How do you override a method in C#?

To override a virtual method in C#, you define a method in a derived class with the same signature as the virtual method in the base class and use the override keyword. This allows the derived class to provide its specific implementation.

What is the difference between virtual and non-virtual methods?

Virtual methods can be overridden in derived classes, allowing for customized behavior, while non-virtual methods cannot be overridden. Non-virtual methods ensure that the base class implementation is used by all derived classes.

Can properties and events be virtual in C#?

Yes, in C#, properties and events can also be marked as virtual. This allows derived classes to provide custom implementations for getters, setters, and event handlers, enhancing the flexibility of class hierarchies.

What are abstract methods and how do they relate to virtual methods?

Abstract methods are declared in an abstract class without an implementation and must be overridden in derived classes. Unlike virtual methods, abstract methods do not provide a default implementation and enforce derived classes to provide one.

What is the difference between method overloading and overriding?

Method overloading occurs within the same class and allows multiple methods with the same name but different parameters. Method overriding, on the other hand, allows a derived class to provide a different implementation for a method defined in the base class using virtual and override keywords.

How does the virtual keyword apply to PDF processing?

The virtual keyword can be used to extend functionality related to PDF generation or manipulation. Developers can create base classes with virtual methods and override these methods in derived classes to customize the PDF processing behavior for specific needs.

What is a practical use case of virtual methods in PDF processing?

A practical use case is customizing PDF rendering. By marking a rendering method as virtual in a base class, derived classes can modify or enhance the rendering process, such as adding watermarks or changing rendering settings.

What is dynamic dispatch in C#?

Dynamic dispatch is a mechanism in C# where the method implementation to be invoked is determined at runtime. This is facilitated by virtual methods and allows for polymorphic behavior, where the correct method implementation is called based on the object's runtime type.

How can developers explore PDF processing capabilities?

Developers can explore PDF processing capabilities using free trial options of tools that allow them to test features and functionalities without any initial cost.

Chipego
Software Engineer
Chipego has a natural skill for listening that helps him to comprehend customer issues, and offer intelligent solutions. He joined the Iron Software team in 2023, after studying a Bachelor of Science in Information Technology. IronPDF and IronOCR are the two products Chipego has been focusing on, but his knowledge of all products is growing daily, as he finds new ways to support customers. He enjoys how collaborative life is at Iron Software, with team members from across the company bringing their varied experience to contribute to effective, innovative solutions. When Chipego is away from his desk, he can often be found enjoying a good book or playing football.