// using System; [assembly:CLSCompliant(true)] public class Number where T : struct { // use Double as the underlying type, since its range is a superset of // the ranges of all numeric types except BigInteger. protected double number; public Number(T value) { try { this.number = Convert.ToDouble(value); } catch (OverflowException e) { throw new ArgumentException("value is too large.", e); } catch (InvalidCastException e) { throw new ArgumentException("The value parameter is not numeric.", e); } } public T Add(T value) { return (T) Convert.ChangeType(number + Convert.ToDouble(value), typeof(T)); } public T Subtract(T value) { return (T) Convert.ChangeType(number - Convert.ToDouble(value), typeof(T)); } } public class FloatingPoint : Number where T : struct { public FloatingPoint(T number) : base(number) { if (typeof(float) == number.GetType() || typeof(double) == number.GetType() || typeof(decimal) == number.GetType()) this.number = Convert.ToDouble(number); else throw new ArgumentException("The number parameter is not a floating-point number."); } } // public class Example { public static void Main() { Number byt = new Number(12); Console.WriteLine(byt.Add(12)); Number sbyt = new Number(-3); Console.WriteLine(sbyt.Subtract(12)); Number ush = new Number(16); Console.WriteLine(ush.Add((ushort)3)); Number dbl = new Number(Math.PI); Console.WriteLine(dbl.Add(1.0)); FloatingPoint sng = new FloatingPoint(12.3f); Console.WriteLine(sng.Add(3.0f)); // FloatingPoint f2 = new FloatingPoint(16); // Console.WriteLine(f2.Add(6)); } }