|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace GenericArithmetic {
public partial class E : GenericArithmetic.TemplateForm {
public E() {
InitializeComponent();
}
}
/// <summary>
/// An abstract base class that defines all of the mathematical operations we might want to do.
/// </summary>
public abstract class MathClass {
public abstract MathClass Add(MathClass other);
public abstract MathClass Subtract(MathClass other);
public abstract MathClass Divide(MathClass other);
public abstract MathClass Divide(int other);
public static MathClass operator +(MathClass a, MathClass b) {
return a.Add(b);
}
public static MathClass operator -(MathClass a, MathClass b) {
return a.Subtract(b);
}
public static MathClass operator /(MathClass a, MathClass b) {
return a.Divide(b);
}
public static MathClass operator /(MathClass a, int b) {
return a.Divide(b);
}
}
/// <summary>
/// Then we can write our SummableList by placing a constraint on the type parameter.
/// Now our summable list can only contain classes that derive from MathClass
/// </summary>
/// <typeparam name="T"></typeparam>
public class SummableListC<T> : List<T> where T : MathClass, new() {
public T Sum() {
T result = new T();
foreach (T thing in this) {
result = (T)(result + thing);
}
return result;
}
public T Average() {
return (T)(Sum() / Count);
}
}
/// <summary>
/// Then we have to create a new class derived from MathClass for any type that we might
/// want to use in our list.
/// Here is the class that lets us use integers in our list.
/// </summary>
public class IntMathClass : MathClass {
private int fValue = 0;
public IntMathClass(int value) {
fValue = value;
}
public IntMathClass() {
fValue = 0;
}
public static implicit operator IntMathClass(int a) {
return new IntMathClass(a);
}
public static implicit operator int(IntMathClass a) {
return a.fValue;
}
public override MathClass Add(MathClass other) {
if (other is IntMathClass) {
return new IntMathClass(this.fValue + (IntMathClass)other);
}
return this;
}
public override MathClass Subtract(MathClass other) {
if (other is IntMathClass) {
return new IntMathClass(this.fValue - (IntMathClass)other);
}
return this;
}
public override MathClass Divide(MathClass other) {
if (other is IntMathClass) {
return new IntMathClass(this.fValue / (IntMathClass)other);
}
return this;
}
public override MathClass Divide(int other) {
return new IntMathClass(this.fValue / other);
}
}
/*
* This method works, but is pretty limiting.
* We can only use classes derived from MathClass.
* Deriving from MathClass requires a relatively large amount of code.
* Preexisting classes would have to be re-written to derive from MathClass because
* there is no multiple inheritence in .Net
*
* However, this does allow us to run the following in the Immediate Window
*
* GenericArithmetic.SummableListC<GenericArithmetic.IntMathClass> list = new GenericArithmetic.SummableListC<GenericArithmetic.IntMathClass>();
*
* list.Add(4);
* list.Add(5);
* list.Add(6);
* list.Add(7);
*
* ?list.Sum();
* ?list.Average();
*/
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.