Skip to content

Instantly share code, notes, and snippets.

@klmr
Created March 6, 2019 14:49
Show Gist options
  • Save klmr/314d05b66c72d62bd8a184514568e22f to your computer and use it in GitHub Desktop.
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
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; }
}
}
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