If you are learning C#
you might as well create a class with the logic you want. In this example I made a ProgressiveTax
object that you can call .Evaluate()
with to calculate taxes.
You can also write or read from XML
strings (which can be written to files)
For example, first populate the tax brackets from PAYE
information provided and save to a file PAYE.xml
. Then forget the tax brackets (out of scope from { }
). And then read the file to populate the tax table from a file
static class Program
{
static void Main(string[] args)
{
{
// create a tax table and save it to a file
var tax = ProgressiveTax.PAYE();
File.WriteAllText("PAYE.xml", tax.ToXml());
}
{
// read a tax table from a file
var tax = ProgressiveTax.FromXml(File.ReadAllText("PAYE.xml"));
// use the tax table
var x = tax.Evaluate(42250m);
Debug.WriteLine($"Tax={x}");
}
}
}
The xml file looks like this, which can be edited manually, or be generated from a database/webservice.
<?xml version="1.0" encoding="utf-16"?>
<ProgressiveTax xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Credit="2400">
<Brackets>
<Bracket>
<Item1>0</Item1>
<Item2>0.1</Item2>
</Bracket>
<Bracket>
<Item1>24000</Item1>
<Item2>0.15</Item2>
</Bracket>
<Bracket>
<Item1>40667</Item1>
<Item2>0.2</Item2>
</Bracket>
<Bracket>
<Item1>57334</Item1>
<Item2>0.25</Item2>
</Bracket>
</Brackets>
</ProgressiveTax>
and the class that actually holds the tax information and calculates the tax amount
public class ProgressiveTax
{
public ProgressiveTax()
{
this.Table = new SortedDictionary<decimal, float>();
}
public ProgressiveTax(SortedDictionary<decimal, float> table)
{
this.Table = table;
}
public static ProgressiveTax PAYE()
{
var tax = new ProgressiveTax();
tax.Credit = 2400m;
tax.Table[0m] = 0.1f;
tax.Table[24000m] = 0.15f;
tax.Table[40667m] = 0.20f;
tax.Table[57334m] = 0.25f;
return tax;
}
public string ToXml()
{
var fs = new StringWriter();
var xs = new XmlSerializer(typeof(ProgressiveTax));
xs.Serialize(fs, this);
fs.Close();
return fs.ToString();
}
public static ProgressiveTax FromXml(string xml)
{
var fs = new StringReader(xml);
var xs = new XmlSerializer(typeof(ProgressiveTax));
var tax = xs.Deserialize(fs) as ProgressiveTax;
fs.Close();
return tax;
}
[XmlAttribute]
public decimal Credit { get; set; }
[XmlIgnore()]
SortedDictionary<decimal, float> Table { get; }
[XmlArrayItem(ElementName = "Bracket")]
public (decimal lower, float rate)[] Brackets
{
get
{
var parts = new (decimal lower, float rate)[Table.Count];
int index = 0;
foreach (var item in Table)
{
parts[index++] = (item.Key, item.Value);
}
return parts;
}
set
{
Table.Clear();
foreach (var (lower, rate) in value)
{
Table[lower] = rate;
}
}
}
public decimal Evaluate(decimal income)
{
decimal result = -Credit;
foreach (var item in Table.Reverse())
{
if (item.Key <= income)
{
Debug.WriteLine($"Assess {item.Value:P2} tax on {income - item.Key}");
result += (decimal)( item.Value * (float) (income - item.Key));
income = item.Key;
}
}
return Math.Max(0m, result);
}
}
The sample program produces the following output in the debugger.
Assess 20.00% tax on 1583
Assess 15.00% tax on 16667
Assess 10.00% tax on 24000
Tax=2816.65
If you add up 1583 + 16667 + 24000 = 42250
which the total amount of income. Since this is a progressive tax, the above rates and amounts are used, and then 2400 is credited. Also not the result must be 0 or positive.