Created
March 6, 2019 14:49
-
-
Save klmr/314d05b66c72d62bd8a184514568e22f to your computer and use it in GitHub Desktop.
Workaround for missing numeric type constraints in C# — https://stackoverflow.com/q/32664/1968
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace OperatorTest { | |
public interface ICalculator { } | |
public interface ICalculator<T> : ICalculator { | |
T Add(T a, T b); | |
T Divide(T a, T b); | |
T Multiply(T a, T b); | |
T Subtract(T a, T b); | |
} | |
static class Calculators { | |
public static readonly Dictionary<Type, ICalculator> calculators = new Dictionary<Type, ICalculator>() { | |
{ typeof(int), new IntCalculator() }, | |
{ typeof(double), new DoubleCalculator() } | |
}; | |
public static ICalculator<T> GetInstance<T>() { | |
return (ICalculator<T>) calculators[typeof(T)]; | |
} | |
} | |
class IntCalculator : ICalculator<int> { | |
public int Add(int a, int b) { return a + b; } | |
public int Divide(int a, int b) { return a / b; } | |
public int Multiply(int a, int b) { return a * b; } | |
public int Subtract(int a, int b) { return a - b; } | |
} | |
class DoubleCalculator : ICalculator<double> { | |
public double Add(double a, double b) { return a + b; } | |
public double Divide(double a, double b) { return a / b; } | |
public double Multiply(double a, double b) { return a * b; } | |
public double Subtract(double a, double b) { return a - b; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace OperatorTest { | |
public class Matrix<T> { | |
private static readonly ICalculator<T> calculator = Calculators.GetInstance<T>(); | |
private readonly int w; | |
private readonly int h; | |
private readonly T[] values; | |
public Matrix(int w, int h) { | |
this.w = w; | |
this.h = h; | |
this.values = new T[w * h]; | |
} | |
public T this[int i, int j] { | |
get { return values[i * w + j]; } | |
set { values[i * w + j] = value; } | |
} | |
public static Matrix<T> operator +(Matrix<T> a, Matrix<T> b) { | |
if (a.w != b.w || a.h != b.h) throw new ArgumentException("Matrices must have compatible dimensions"); | |
var ret = new Matrix<T>(a.w, a.h); | |
for (int i = 0; i < a.values.Length; i++) { | |
ret.values[i] = calculator.Add(a.values[i], b.values[i]); | |
} | |
return ret; | |
} | |
public override string ToString() { | |
var sb = new System.Text.StringBuilder(); | |
for (int i = 0; i < h; i++) { | |
if (i != 0) sb.Append("\n "); | |
for (int j = 0; j < w; j++) { | |
if (j != 0) sb.Append(", "); | |
sb.Append(this[i, j]); | |
} | |
} | |
return $"{{{sb}}}"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment