Last Update: 9 February, 2005

In complex applications written in C#, we may need many methods which do essentially similar functions but are just different enough to be considered unique. For example, we may have to calculate a person’s tax liability and would need to implement a method for doing this calculation in our application program. However, there are many different rules when it comes to tax calculations and they vary throughout the world. While there may be many rules, one basic equation stays the same: Your net income equals your gross income minus a computed tax amount. It is the method of computing your tax that varies.

We would probably have to implement different methods for each type of tax calculation. And, we could give each method a unique name such as TaxCalc1, TaxCalc2, TaxCalc3, etc. But wouldn’t it be nice to just name the method TaxCalc and pass different arguments to it based on the computation desired?

For instance, let’s say you live in a region within your country where you are taxed on your personal income, the value of your home, and any income you generate by doing business. On sales you generate through business activity, you must pay a gross receipts tax on all sales. If you own your home, you must pay a property tax on the imputed value of it. Then lastly, you must pay a tax on all income you generate through a job with another employer.

## An Example: Tax Calculation

For this article, we will use a hypothetical example of computing various taxes on a person’s property, sales, and income. Let’s summarize the logical flow through pseudocode:

 HV = Home_Value HR = Home_Tax_Rate GS = Gross_Sales GR = Gross_Sales_Tax_Rate PI = Personal IncomeIf YOU_OWN_YOUR_OWN_HOME and DO_NOT_OWN_A_BUSINESS THEN Tax = TaxCalc(HV,HR)    ‘ Calculate tax on the home’s value ELSE If  YOU_DO_NOT_OWN_YOUR_OWN_HOME and OWN_A_BUSINESS THEN Tax = TaxCalc(GS,GR)   ‘ Calculate tax on your gross receipts from sales ELSE If YOU_OWN_YOUR_OWN_HOME and OWN_A_BUSINESS THEN Tax = TaxCalc(HV,HR,GS,GR)   ‘ Calculate tax on both your home and gross receipts ENDIF ENDIF ENDIFTax = Tax + TaxCalc(PI)   ‘ And everyone gets a tax calculation on personal income

The pseudo code says that if you own your own home but do not have a business, then you will calculate your tax based on the home’s value and the tax rate on a home. If you don’t own a home but you own a business then you will calculate your tax based on your gross sales and gross sales tax rate. Finally, if you own a home and a business then you will call TaxCalc and pass all four values. Everyone is run through the TaxCalc method for personal income tax. We don’t have to pass a rate for personal income tax calculation because everyone is at a fixed rate which is embedded within the method.

Keep in mind that this example of tax calculation is all hypothetical. Tax codes and calculations, as you know, are much more complex than what is described here throughout the world. But for the sake of this example, we see that we have a method named TaxCalc that is able to take one, two, or four arguments based upon the type of tax we are calculating. Without method overloading, we would have to create a unique method name for each type of calculation we would have to do. We would probably name each TaxCalc1, TaxCalc2, and TaxCalc3 respectively.

How does C# know which method to call? It’s easy. It knows which method to invoke based on the number and type of arguments passed to it. This is also referred to as the signature of the method. If C# sees you are calling TaxCalc with four arguments, then it will call that method with four receiving arguments. The same is true for the other two methods as well.

 // This method takes for arguments: two amounts and two rates public static double TaxCalc(double pamt1, double prate1, double pamt2, double prate2) { double taxamt; Console.WriteLine(“Using method with 4 arguments”); taxamt = (pamt1 * prate1) + (pamt2 * prate2); return taxamt;} // *** TaxCalc ***// This method only takes two arguments: an amount and a rate public static double TaxCalc(double pamt1, double prate1) { double taxamt; Console.WriteLine(“Using method with 2 arguments”); taxamt = pamt1 * prate1; return taxamt; } // *** TaxCalc *** // This method only takes one argument: an amount public static double TaxCalc(double pamt) { double taxrate = 0.15; double taxamt = 0; Console.WriteLine(“Using method with 1 argument”); taxamt = pamt * taxrate; return taxamt; } // *** TaxCalc ***

The methods are all very similar however they are differ by the number of arguments used in the tax calculation. If we have two tax rates and two amounts, C# would pick the first method based on four arguments and invoke that. The same holds true for the other two methods.

Caveat

It is important to remember that C# determines which method to call based upon the method’s signature. If you were to define two methods with the same name and the same number and type of passed arguments, you would get a compile-time error in Visual Studio .NET of:

Class1.cs(53): Class ‘MethodOverload.MainClass’ already defines a member called ‘TaxCalc’ with the same parameter types

However, you can have two methods with the same name and the same number of arguments as long as the argument types differ. Let’s say, for instance, that you want to have another one-argument method named TaxCalc that takes a string argument. If the string is the literal “TaxTable1″, then it will return the tax rate used in personal tax calculations:

 // This method only takes one argument as well but it differs // from the above in the argument type.public static double TaxCalc(string whichtable) { double taxrate = 0; Console.WriteLine(“Calling the method with on string argument”); if (whichtable == “TaxTable1″) taxrate = 0.15;return taxrate; } // *** TaxCalc ***

This article has an example application available for download with the above methods. It is a C#.NET console application and can be invoked from a Dos command window by typing in methodoverload in the folder containing methodoverload.exe. The main driver implements the pseudocode we defined previously: