Repository: BayesWitnesses/m2cgen (language: rust)

Issue:
C# support
Is there a roadmap for converting models to C# code? I work at a Microsoft shop and this would be great to use instead of ML.NET since this is so much more lightweight. Thanks!


Discussion / hints:
Hey @mattc-eostar! 

We don't have a roadmap for C# support since it wasn't exactly clear whether there is a demand for it. Now, however, you've provided a clear indication that there is one :) Thank you for considering using this project!

I personally have never worked with C# before and to the best of my knowledge nobody from this project team have any experience with it either. Would you perhaps consider contributing it? I believe you can take Java/JS as an example and replicate it with C# constructs. People who were not familiar with the codebase at all have successfully contributed Golang and JS support in the past. You can look at their commits as a reference too. And of course we're always here to help.

Otherwise I'll definitely work on it at some point but unfortunately can't commit to any particular date. 
Not a problem, I will see what I can do. Thank you for the quick response. This wouldn't be a show-stopper for us by any means, but a neat tool in our toolbox.
I would have to guess that the code would look extremely similar to the Java output. I will be AFK for the next two weeks, so it may have to wait until after that unless someone else feels compelled to do it.

Fix patch:
diff --git a/README.md b/README.md
index 0d84b2a1..eb09467b 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
 [![Python Versions](https://img.shields.io/pypi/pyversions/m2cgen.svg?logo=python&logoColor=white)](https://pypi.org/project/m2cgen)
 [![PyPI Version](https://img.shields.io/pypi/v/m2cgen.svg?logo=pypi&logoColor=white)](https://pypi.org/project/m2cgen)
 
-**m2cgen** (Model 2 Code Generator) - is a lightweight library which provides an easy way to transpile trained statistical models into a native code (Python, C, Java, Go, JavaScript, Visual Basic).
+**m2cgen** (Model 2 Code Generator) - is a lightweight library which provides an easy way to transpile trained statistical models into a native code (Python, C, Java, Go, JavaScript, Visual Basic, C#).
 
 * [Installation](#installation)
 * [Supported Languages](#supported-languages)
@@ -26,6 +26,7 @@ pip install m2cgen
 ## Supported Languages
 
 - C
+- C#
 - Go
 - Java
 - JavaScript
@@ -100,8 +101,8 @@ public class Model {
 
 `m2cgen` can be used as a CLI tool to generate code using serialized model objects (pickle protocol):
 ```
-$ m2cgen <pickle_file> --language <language> [--indent <indent>]
-         [--class_name <class_name>] [--module_name <module_name>] [--package_name <package_name>]
+$ m2cgen <pickle_file> --language <language> [--indent <indent>] [--class_name <class_name>]
+         [--module_name <module_name>] [--package_name <package_name>] [--namespace <namespace>]
          [--recursion-limit <recursion_limit>]
 ```
 
diff --git a/generated_code_examples/c_sharp/classification/decision_tree.cs b/generated_code_examples/c_sharp/classification/decision_tree.cs
new file mode 100644
index 00000000..1b1a2e85
--- /dev/null
+++ b/generated_code_examples/c_sharp/classification/decision_tree.cs
@@ -0,0 +1,25 @@
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            double[] var0;
+            if ((input[2]) <= (2.6)) {
+                var0 = new double[3] {1.0, 0.0, 0.0};
+            } else {
+                if ((input[2]) <= (4.8500004)) {
+                    if ((input[3]) <= (1.6500001)) {
+                        var0 = new double[3] {0.0, 1.0, 0.0};
+                    } else {
+                        var0 = new double[3] {0.0, 0.3333333333333333, 0.6666666666666666};
+                    }
+                } else {
+                    if ((input[3]) <= (1.75)) {
+                        var0 = new double[3] {0.0, 0.42857142857142855, 0.5714285714285714};
+                    } else {
+                        var0 = new double[3] {0.0, 0.0, 1.0};
+                    }
+                }
+            }
+            return var0;
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/classification/lightgbm.cs b/generated_code_examples/c_sharp/classification/lightgbm.cs
new file mode 100644
index 00000000..9da0de3d
--- /dev/null
+++ b/generated_code_examples/c_sharp/classification/lightgbm.cs
@@ -0,0 +1,84 @@
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            double var0;
+            if ((input[2]) > (1.8)) {
+                if ((input[2]) > (4.250000000000001)) {
+                    var0 = -1.1736122903444903;
+                } else {
+                    var0 = -1.1633850173886202;
+                }
+            } else {
+                var0 = -0.9486122853153485;
+            }
+            double var1;
+            if ((input[2]) > (1.8)) {
+                if ((input[1]) > (3.0500000000000003)) {
+                    var1 = -0.06193194743580539;
+                } else {
+                    var1 = -0.07237070828653688;
+                }
+            } else {
+                var1 = 0.12984943093573026;
+            }
+            double var2;
+            var2 = Exp(((0) + (var0)) + (var1));
+            double var3;
+            if ((input[2]) > (1.8)) {
+                if ((input[2]) > (4.8500000000000005)) {
+                    var3 = -1.1807342692411888;
+                } else {
+                    var3 = -0.9831932134295853;
+                }
+            } else {
+                var3 = -1.1952609652674462;
+            }
+            double var4;
+            if ((input[2]) > (1.8)) {
+                if ((input[2]) > (4.8500000000000005)) {
+                    var4 = -0.05694282927518771;
+                } else {
+                    var4 = 0.11960489254350348;
+                }
+            } else {
+                var4 = -0.07151978915296087;
+            }
+            double var5;
+            var5 = Exp(((0) + (var3)) + (var4));
+            double var6;
+            if ((input[2]) > (4.8500000000000005)) {
+                if ((input[3]) > (1.9500000000000002)) {
+                    var6 = -0.9298942558407184;
+                } else {
+                    var6 = -0.9632815288936335;
+                }
+            } else {
+                if ((input[2]) > (4.250000000000001)) {
+                    var6 = -1.1322413652523249;
+                } else {
+                    var6 = -1.1524760761934856;
+                }
+            }
+            double var7;
+            if ((input[2]) > (4.8500000000000005)) {
+                if ((input[3]) > (1.9500000000000002)) {
+                    var7 = 0.12809276954555665;
+                } else {
+                    var7 = 0.09898817876916756;
+                }
+            } else {
+                if ((input[2]) > (4.250000000000001)) {
+                    var7 = -0.052710589717642864;
+                } else {
+                    var7 = -0.07292857712854424;
+                }
+            }
+            double var8;
+            var8 = Exp(((0) + (var6)) + (var7));
+            double var9;
+            var9 = ((var2) + (var5)) + (var8);
+            return new double[3] {(var2) / (var9), (var5) / (var9), (var8) / (var9)};
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/classification/linear.cs b/generated_code_examples/c_sharp/classification/linear.cs
new file mode 100644
index 00000000..1e29cfd2
--- /dev/null
+++ b/generated_code_examples/c_sharp/classification/linear.cs
@@ -0,0 +1,7 @@
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            return new double[3] {((((0.2614587435880605) + ((input[0]) * (0.42474116053569605))) + ((input[1]) * (1.3963906033045026))) + ((input[2]) * (-2.215054318516674))) + ((input[3]) * (-0.9587396176450289)), ((((1.1348839223808307) + ((input[0]) * (0.2567965976997648))) + ((input[1]) * (-1.3904789369836008))) + ((input[2]) * (0.596683023311173))) + ((input[3]) * (-1.2690022726388828)), ((((-1.2162802012560197) + ((input[0]) * (-1.6357766989177105))) + ((input[1]) * (-1.5040638728422817))) + ((input[2]) * (2.427835933129272))) + ((input[3]) * (2.3469310693367276))};
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/classification/random_forest.cs b/generated_code_examples/c_sharp/classification/random_forest.cs
new file mode 100644
index 00000000..811a2be5
--- /dev/null
+++ b/generated_code_examples/c_sharp/classification/random_forest.cs
@@ -0,0 +1,57 @@
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            double[] var0;
+            if ((input[3]) <= (0.8)) {
+                var0 = new double[3] {1.0, 0.0, 0.0};
+            } else {
+                if ((input[2]) <= (4.8500004)) {
+                    var0 = new double[3] {0.0, 0.9795918367346939, 0.02040816326530612};
+                } else {
+                    if ((input[3]) <= (1.75)) {
+                        if ((input[3]) <= (1.6500001)) {
+                            var0 = new double[3] {0.0, 0.25, 0.75};
+                        } else {
+                            var0 = new double[3] {0.0, 1.0, 0.0};
+                        }
+                    } else {
+                        var0 = new double[3] {0.0, 0.0, 1.0};
+                    }
+                }
+            }
+            double[] var1;
+            if ((input[3]) <= (0.8)) {
+                var1 = new double[3] {1.0, 0.0, 0.0};
+            } else {
+                if ((input[0]) <= (6.05)) {
+                    if ((input[2]) <= (4.9)) {
+                        var1 = new double[3] {0.0, 0.9032258064516129, 0.0967741935483871};
+                    } else {
+                        var1 = new double[3] {0.0, 0.0, 1.0};
+                    }
+                } else {
+                    if ((input[3]) <= (1.75)) {
+                        var1 = new double[3] {0.0, 0.8, 0.2};
+                    } else {
+                        var1 = new double[3] {0.0, 0.0, 1.0};
+                    }
+                }
+            }
+            return AddVectors(MulVectorNumber(var0, 0.5), MulVectorNumber(var1, 0.5));
+        }
+        private static double[] AddVectors(double[] v1, double[] v2) {
+            double[] result = new double[v1.Length];
+            for (int i = 0; i < v1.Length; ++i) {
+                result[i] = v1[i] + v2[i];
+            }
+            return result;
+        }
+        private static double[] MulVectorNumber(double[] v1, double num) {
+            double[] result = new double[v1.Length];
+            for (int i = 0; i < v1.Length; ++i) {
+                result[i] = v1[i] * num;
+            }
+            return result;
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/classification/svm.cs b/generated_code_examples/c_sharp/classification/svm.cs
new file mode 100644
index 00000000..4b99a802
--- /dev/null
+++ b/generated_code_examples/c_sharp/classification/svm.cs
@@ -0,0 +1,74 @@
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            double var0;
+            var0 = (0) - (0.25);
+            double var1;
+            var1 = Exp((var0) * ((((Pow((5.4) - (input[0]), 2)) + (Pow((3.0) - (input[1]), 2))) + (Pow((4.5) - (input[2]), 2))) + (Pow((1.5) - (input[3]), 2))));
+            double var2;
+            var2 = Exp((var0) * ((((Pow((6.2) - (input[0]), 2)) + (Pow((2.2) - (input[1]), 2))) + (Pow((4.5) - (input[2]), 2))) + (Pow((1.5) - (input[3]), 2))));
+            double var3;
+            var3 = Exp((var0) * ((((Pow((5.0) - (input[0]), 2)) + (Pow((2.3) - (input[1]), 2))) + (Pow((3.3) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))));
+            double var4;
+            var4 = Exp((var0) * ((((Pow((5.9) - (input[0]), 2)) + (Pow((3.2) - (input[1]), 2))) + (Pow((4.8) - (input[2]), 2))) + (Pow((1.8) - (input[3]), 2))));
+            double var5;
+            var5 = Exp((var0) * ((((Pow((5.0) - (input[0]), 2)) + (Pow((2.0) - (input[1]), 2))) + (Pow((3.5) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))));
+            double var6;
+            var6 = Exp((var0) * ((((Pow((6.7) - (input[0]), 2)) + (Pow((3.0) - (input[1]), 2))) + (Pow((5.0) - (input[2]), 2))) + (Pow((1.7) - (input[3]), 2))));
+            double var7;
+            var7 = Exp((var0) * ((((Pow((7.0) - (input[0]), 2)) + (Pow((3.2) - (input[1]), 2))) + (Pow((4.7) - (input[2]), 2))) + (Pow((1.4) - (input[3]), 2))));
+            double var8;
+            var8 = Exp((var0) * ((((Pow((4.9) - (input[0]), 2)) + (Pow((2.4) - (input[1]), 2))) + (Pow((3.3) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))));
+            double var9;
+            var9 = Exp((var0) * ((((Pow((6.3) - (input[0]), 2)) + (Pow((2.5) - (input[1]), 2))) + (Pow((4.9) - (input[2]), 2))) + (Pow((1.5) - (input[3]), 2))));
+            double var10;
+            var10 = Exp((var0) * ((((Pow((6.0) - (input[0]), 2)) + (Pow((2.7) - (input[1]), 2))) + (Pow((5.1) - (input[2]), 2))) + (Pow((1.6) - (input[3]), 2))));
+            double var11;
+            var11 = Exp((var0) * ((((Pow((5.7) - (input[0]), 2)) + (Pow((2.6) - (input[1]), 2))) + (Pow((3.5) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))));
+            double var12;
+            var12 = Exp((var0) * ((((Pow((5.1) - (input[0]), 2)) + (Pow((3.8) - (input[1]), 2))) + (Pow((1.9) - (input[2]), 2))) + (Pow((0.4) - (input[3]), 2))));
+            double var13;
+            var13 = Exp((var0) * ((((Pow((4.4) - (input[0]), 2)) + (Pow((2.9) - (input[1]), 2))) + (Pow((1.4) - (input[2]), 2))) + (Pow((0.2) - (input[3]), 2))));
+            double var14;
+            var14 = Exp((var0) * ((((Pow((5.7) - (input[0]), 2)) + (Pow((4.4) - (input[1]), 2))) + (Pow((1.5) - (input[2]), 2))) + (Pow((0.4) - (input[3]), 2))));
+            double var15;
+            var15 = Exp((var0) * ((((Pow((5.8) - (input[0]), 2)) + (Pow((4.0) - (input[1]), 2))) + (Pow((1.2) - (input[2]), 2))) + (Pow((0.2) - (input[3]), 2))));
+            double var16;
+            var16 = Exp((var0) * ((((Pow((5.1) - (input[0]), 2)) + (Pow((3.3) - (input[1]), 2))) + (Pow((1.7) - (input[2]), 2))) + (Pow((0.5) - (input[3]), 2))));
+            double var17;
+            var17 = Exp((var0) * ((((Pow((5.7) - (input[0]), 2)) + (Pow((3.8) - (input[1]), 2))) + (Pow((1.7) - (input[2]), 2))) + (Pow((0.3) - (input[3]), 2))));
+            double var18;
+            var18 = Exp((var0) * ((((Pow((4.3) - (input[0]), 2)) + (Pow((3.0) - (input[1]), 2))) + (Pow((1.1) - (input[2]), 2))) + (Pow((0.1) - (input[3]), 2))));
+            double var19;
+            var19 = Exp((var0) * ((((Pow((4.5) - (input[0]), 2)) + (Pow((2.3) - (input[1]), 2))) + (Pow((1.3) - (input[2]), 2))) + (Pow((0.3) - (input[3]), 2))));
+            double var20;
+            var20 = Exp((var0) * ((((Pow((6.3) - (input[0]), 2)) + (Pow((2.7) - (input[1]), 2))) + (Pow((4.9) - (input[2]), 2))) + (Pow((1.8) - (input[3]), 2))));
+            double var21;
+            var21 = Exp((var0) * ((((Pow((6.0) - (input[0]), 2)) + (Pow((3.0) - (input[1]), 2))) + (Pow((4.8) - (input[2]), 2))) + (Pow((1.8) - (input[3]), 2))));
+            double var22;
+            var22 = Exp((var0) * ((((Pow((6.3) - (input[0]), 2)) + (Pow((2.8) - (input[1]), 2))) + (Pow((5.1) - (input[2]), 2))) + (Pow((1.5) - (input[3]), 2))));
+            double var23;
+            var23 = Exp((var0) * ((((Pow((5.8) - (input[0]), 2)) + (Pow((2.8) - (input[1]), 2))) + (Pow((5.1) - (input[2]), 2))) + (Pow((2.4) - (input[3]), 2))));
+            double var24;
+            var24 = Exp((var0) * ((((Pow((6.1) - (input[0]), 2)) + (Pow((3.0) - (input[1]), 2))) + (Pow((4.9) - (input[2]), 2))) + (Pow((1.8) - (input[3]), 2))));
+            double var25;
+            var25 = Exp((var0) * ((((Pow((7.7) - (input[0]), 2)) + (Pow((2.6) - (input[1]), 2))) + (Pow((6.9) - (input[2]), 2))) + (Pow((2.3) - (input[3]), 2))));
+            double var26;
+            var26 = Exp((var0) * ((((Pow((6.9) - (input[0]), 2)) + (Pow((3.1) - (input[1]), 2))) + (Pow((5.1) - (input[2]), 2))) + (Pow((2.3) - (input[3]), 2))));
+            double var27;
+            var27 = Exp((var0) * ((((Pow((6.3) - (input[0]), 2)) + (Pow((3.3) - (input[1]), 2))) + (Pow((6.0) - (input[2]), 2))) + (Pow((2.5) - (input[3]), 2))));
+            double var28;
+            var28 = Exp((var0) * ((((Pow((4.9) - (input[0]), 2)) + (Pow((2.5) - (input[1]), 2))) + (Pow((4.5) - (input[2]), 2))) + (Pow((1.7) - (input[3]), 2))));
+            double var29;
+            var29 = Exp((var0) * ((((Pow((6.0) - (input[0]), 2)) + (Pow((2.2) - (input[1]), 2))) + (Pow((5.0) - (input[2]), 2))) + (Pow((1.5) - (input[3]), 2))));
+            double var30;
+            var30 = Exp((var0) * ((((Pow((7.9) - (input[0]), 2)) + (Pow((3.8) - (input[1]), 2))) + (Pow((6.4) - (input[2]), 2))) + (Pow((2.0) - (input[3]), 2))));
+            double var31;
+            var31 = Exp((var0) * ((((Pow((7.2) - (input[0]), 2)) + (Pow((3.0) - (input[1]), 2))) + (Pow((5.8) - (input[2]), 2))) + (Pow((1.6) - (input[3]), 2))));
+            double var32;
+            var32 = Exp((var0) * ((((Pow((7.7) - (input[0]), 2)) + (Pow((3.8) - (input[1]), 2))) + (Pow((6.7) - (input[2]), 2))) + (Pow((2.2) - (input[3]), 2))));
+            return new double[3] {(((((((((((((((((((-0.08359187780790468) + ((var1) * (-0.0))) + ((var2) * (-0.0))) + ((var3) * (-0.4393498355605194))) + ((var4) * (-0.009465620856664334))) + ((var5) * (-0.16223369966927))) + ((var6) * (-0.26861888775075243))) + ((var7) * (-0.4393498355605194))) + ((var8) * (-0.4393498355605194))) + ((var9) * (-0.0))) + ((var10) * (-0.0))) + ((var11) * (-0.19673905328606292))) + ((var12) * (0.3340655283922188))) + ((var13) * (0.3435087305152051))) + ((var14) * (0.4393498355605194))) + ((var15) * (0.0))) + ((var16) * (0.28614124535416424))) + ((var17) * (0.11269159286168087))) + ((var18) * (0.0))) + ((var19) * (0.4393498355605194)), (((((((((((((((((((((-0.18563912331454907) + ((var20) * (-0.0))) + ((var21) * (-0.06014273244194299))) + ((var22) * (-0.0))) + ((var23) * (-0.031132453078851926))) + ((var24) * (-0.0))) + ((var25) * (-0.3893079321588921))) + ((var26) * (-0.06738007627290196))) + ((var27) * (-0.1225075748937126))) + ((var28) * (-0.3893079321588921))) + ((var29) * (-0.29402231709614085))) + ((var30) * (-0.3893079321588921))) + ((var31) * (-0.0))) + ((var32) * (-0.028242141062729226))) + ((var12) * (0.16634667752431267))) + ((var13) * (0.047772685163074764))) + ((var14) * (0.3893079321588921))) + ((var15) * (0.3893079321588921))) + ((var16) * (0.0))) + ((var17) * (0.0))) + ((var18) * (0.3893079321588921))) + ((var19) * (0.3893079321588921)), ((((((((((((((((((((((((0.5566649875797668) + ((var20) * (-25.563066587228416))) + ((var21) * (-38.35628154976547))) + ((var22) * (-38.35628154976547))) + ((var23) * (-0.0))) + ((var24) * (-38.35628154976547))) + ((var25) * (-0.0))) + ((var26) * (-0.0))) + ((var27) * (-0.0))) + ((var28) * (-6.2260303727828745))) + ((var29) * (-18.42781911624364))) + ((var30) * (-0.14775026537286423))) + ((var31) * (-7.169755983020096))) + ((var32) * (-0.0))) + ((var1) * (12.612328267927264))) + ((var2) * (6.565812506955159))) + ((var3) * (0.0))) + ((var4) * (38.35628154976547))) + ((var5) * (0.0))) + ((var6) * (38.35628154976547))) + ((var7) * (0.0))) + ((var8) * (0.0))) + ((var9) * (38.35628154976547))) + ((var10) * (38.35628154976547))) + ((var11) * (0.0))};
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/classification/xgboost.cs b/generated_code_examples/c_sharp/classification/xgboost.cs
new file mode 100644
index 00000000..f1b8c497
--- /dev/null
+++ b/generated_code_examples/c_sharp/classification/xgboost.cs
@@ -0,0 +1,76 @@
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            double var0;
+            if ((input[2]) >= (2.5999999)) {
+                var0 = -0.0731707439;
+            } else {
+                var0 = 0.142857149;
+            }
+            double var1;
+            if ((input[2]) >= (2.5999999)) {
+                var1 = -0.0705206916;
+            } else {
+                var1 = 0.12477719;
+            }
+            double var2;
+            var2 = Exp(((0.5) + (var0)) + (var1));
+            double var3;
+            if ((input[2]) >= (2.5999999)) {
+                if ((input[2]) >= (4.85000038)) {
+                    var3 = -0.0578680299;
+                } else {
+                    var3 = 0.132596686;
+                }
+            } else {
+                var3 = -0.0714285821;
+            }
+            double var4;
+            if ((input[2]) >= (2.5999999)) {
+                if ((input[2]) >= (4.85000038)) {
+                    var4 = -0.0552999265;
+                } else {
+                    var4 = 0.116139404;
+                }
+            } else {
+                var4 = -0.0687687024;
+            }
+            double var5;
+            var5 = Exp(((0.5) + (var3)) + (var4));
+            double var6;
+            if ((input[2]) >= (4.85000038)) {
+                if ((input[3]) >= (1.75)) {
+                    var6 = 0.142011836;
+                } else {
+                    var6 = 0.0405405387;
+                }
+            } else {
+                if ((input[3]) >= (1.6500001)) {
+                    var6 = 0.0428571403;
+                } else {
+                    var6 = -0.0730659068;
+                }
+            }
+            double var7;
+            if ((input[2]) >= (4.85000038)) {
+                if ((input[3]) >= (1.75)) {
+                    var7 = 0.124653697;
+                } else {
+                    var7 = 0.035562478;
+                }
+            } else {
+                if ((input[3]) >= (1.6500001)) {
+                    var7 = 0.0425687581;
+                } else {
+                    var7 = -0.0704230517;
+                }
+            }
+            double var8;
+            var8 = Exp(((0.5) + (var6)) + (var7));
+            double var9;
+            var9 = ((var2) + (var5)) + (var8);
+            return new double[3] {(var2) / (var9), (var5) / (var9), (var8) / (var9)};
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/regression/decision_tree.cs b/generated_code_examples/c_sharp/regression/decision_tree.cs
new file mode 100644
index 00000000..6775b406
--- /dev/null
+++ b/generated_code_examples/c_sharp/regression/decision_tree.cs
@@ -0,0 +1,25 @@
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            if ((input[5]) <= (6.941)) {
+                if ((input[12]) <= (14.395)) {
+                    if ((input[7]) <= (1.43365)) {
+                        var0 = 45.58;
+                    } else {
+                        var0 = 22.865022421524642;
+                    }
+                } else {
+                    var0 = 14.924358974358983;
+                }
+            } else {
+                if ((input[5]) <= (7.4370003)) {
+                    var0 = 32.09534883720931;
+                } else {
+                    var0 = 45.275;
+                }
+            }
+            return var0;
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/regression/lightgbm.cs b/generated_code_examples/c_sharp/regression/lightgbm.cs
new file mode 100644
index 00000000..4758e96e
--- /dev/null
+++ b/generated_code_examples/c_sharp/regression/lightgbm.cs
@@ -0,0 +1,35 @@
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            if ((input[5]) > (6.8455)) {
+                if ((input[5]) > (7.437)) {
+                    var0 = 24.906664851995615;
+                } else {
+                    var0 = 23.513674700555555;
+                }
+            } else {
+                if ((input[12]) > (14.395000000000001)) {
+                    var0 = 21.863487452747595;
+                } else {
+                    var0 = 22.70305627629392;
+                }
+            }
+            double var1;
+            if ((input[12]) > (9.63)) {
+                if ((input[12]) > (19.830000000000002)) {
+                    var1 = -0.9644646678713786;
+                } else {
+                    var1 = -0.30629733662250097;
+                }
+            } else {
+                if ((input[5]) > (7.437)) {
+                    var1 = 2.0368334157126293;
+                } else {
+                    var1 = 0.4576204330349962;
+                }
+            }
+            return ((0) + (var0)) + (var1);
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/regression/linear.cs b/generated_code_examples/c_sharp/regression/linear.cs
new file mode 100644
index 00000000..c032ae74
--- /dev/null
+++ b/generated_code_examples/c_sharp/regression/linear.cs
@@ -0,0 +1,7 @@
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            return (((((((((((((36.006810733650326) + ((input[0]) * (-0.10081655845910407))) + ((input[1]) * (0.04403556956079904))) + ((input[2]) * (0.030804434213336))) + ((input[3]) * (2.9326736094672676))) + ((input[4]) * (-17.09336013214799))) + ((input[5]) * (3.74506822086355))) + ((input[6]) * (0.0033774353698562175))) + ((input[7]) * (-1.4348015681660853))) + ((input[8]) * (0.2901581119428308))) + ((input[9]) * (-0.011463487956327859))) + ((input[10]) * (-0.9500012437313143))) + ((input[11]) * (0.010374330909981067))) + ((input[12]) * (-0.5713890449294768));
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/regression/random_forest.cs b/generated_code_examples/c_sharp/regression/random_forest.cs
new file mode 100644
index 00000000..d1db0367
--- /dev/null
+++ b/generated_code_examples/c_sharp/regression/random_forest.cs
@@ -0,0 +1,43 @@
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            if ((input[5]) <= (6.92)) {
+                if ((input[12]) <= (14.3)) {
+                    if ((input[7]) <= (1.47415)) {
+                        var0 = 50.0;
+                    } else {
+                        var0 = 23.203669724770638;
+                    }
+                } else {
+                    var0 = 15.177333333333326;
+                }
+            } else {
+                if ((input[5]) <= (7.4370003)) {
+                    var0 = 32.92407407407408;
+                } else {
+                    var0 = 45.04827586206897;
+                }
+            }
+            double var1;
+            if ((input[12]) <= (9.725)) {
+                if ((input[5]) <= (7.4525)) {
+                    if ((input[5]) <= (6.7539997)) {
+                        var1 = 24.805;
+                    } else {
+                        var1 = 32.55238095238095;
+                    }
+                } else {
+                    var1 = 47.88333333333334;
+                }
+            } else {
+                if ((input[12]) <= (15.0)) {
+                    var1 = 20.52100840336134;
+                } else {
+                    var1 = 14.718709677419358;
+                }
+            }
+            return ((var0) * (0.5)) + ((var1) * (0.5));
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/regression/svm.cs b/generated_code_examples/c_sharp/regression/svm.cs
new file mode 100644
index 00000000..b8e43cd8
--- /dev/null
+++ b/generated_code_examples/c_sharp/regression/svm.cs
@@ -0,0 +1,10 @@
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            var0 = (0) - (0.07692307692307693);
+            return ((((((((((((((((((((((((((((((((((((((((((((((((((((27.02162490523095) + ((Exp((var0) * (((((((((((((Pow((25.9406) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.679) - (input[4]), 2))) + (Pow((5.304) - (input[5]), 2))) + (Pow((89.1) - (input[6]), 2))) + (Pow((1.6475) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((127.36) - (input[11]), 2))) + (Pow((26.64) - (input[12]), 2))))) * (-0.11849528386764518))) + ((Exp((var0) * (((((((((((((Pow((6.53876) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.631) - (input[4]), 2))) + (Pow((7.016) - (input[5]), 2))) + (Pow((97.5) - (input[6]), 2))) + (Pow((1.2024) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((392.05) - (input[11]), 2))) + (Pow((2.96) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((22.5971) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.7) - (input[4]), 2))) + (Pow((5.0) - (input[5]), 2))) + (Pow((89.5) - (input[6]), 2))) + (Pow((1.5184) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((31.99) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((45.7461) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((4.519) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.6582) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((88.27) - (input[11]), 2))) + (Pow((36.98) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((11.8123) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.718) - (input[4]), 2))) + (Pow((6.824) - (input[5]), 2))) + (Pow((76.5) - (input[6]), 2))) + (Pow((1.794) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((48.45) - (input[11]), 2))) + (Pow((22.74) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.08187) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((2.89) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.445) - (input[4]), 2))) + (Pow((7.82) - (input[5]), 2))) + (Pow((36.9) - (input[6]), 2))) + (Pow((3.4952) - (input[7]), 2))) + (Pow((2.0) - (input[8]), 2))) + (Pow((276.0) - (input[9]), 2))) + (Pow((18.0) - (input[10]), 2))) + (Pow((393.53) - (input[11]), 2))) + (Pow((3.57) - (input[12]), 2))))) * (0.2750000000382897))) + ((Exp((var0) * (((((((((((((Pow((7.67202) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((5.747) - (input[5]), 2))) + (Pow((98.9) - (input[6]), 2))) + (Pow((1.6334) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((393.1) - (input[11]), 2))) + (Pow((19.92) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((1.46336) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((19.58) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.605) - (input[4]), 2))) + (Pow((7.489) - (input[5]), 2))) + (Pow((90.8) - (input[6]), 2))) + (Pow((1.9709) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((403.0) - (input[9]), 2))) + (Pow((14.7) - (input[10]), 2))) + (Pow((374.43) - (input[11]), 2))) + (Pow((1.73) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((20.0849) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.7) - (input[4]), 2))) + (Pow((4.368) - (input[5]), 2))) + (Pow((91.2) - (input[6]), 2))) + (Pow((1.4395) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((285.83) - (input[11]), 2))) + (Pow((30.63) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((1.83377) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((19.58) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.605) - (input[4]), 2))) + (Pow((7.802) - (input[5]), 2))) + (Pow((98.2) - (input[6]), 2))) + (Pow((2.0407) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((403.0) - (input[9]), 2))) + (Pow((14.7) - (input[10]), 2))) + (Pow((389.61) - (input[11]), 2))) + (Pow((1.92) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((73.5341) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.679) - (input[4]), 2))) + (Pow((5.957) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.8026) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((16.45) - (input[11]), 2))) + (Pow((20.62) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.33147) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((6.2) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.507) - (input[4]), 2))) + (Pow((8.247) - (input[5]), 2))) + (Pow((70.4) - (input[6]), 2))) + (Pow((3.6519) - (input[7]), 2))) + (Pow((8.0) - (input[8]), 2))) + (Pow((307.0) - (input[9]), 2))) + (Pow((17.4) - (input[10]), 2))) + (Pow((378.95) - (input[11]), 2))) + (Pow((3.95) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((25.0461) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((5.987) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.5888) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((26.77) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.57834) - (input[0]), 2)) + (Pow((20.0) - (input[1]), 2))) + (Pow((3.97) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.575) - (input[4]), 2))) + (Pow((8.297) - (input[5]), 2))) + (Pow((67.0) - (input[6]), 2))) + (Pow((2.4216) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((264.0) - (input[9]), 2))) + (Pow((13.0) - (input[10]), 2))) + (Pow((384.54) - (input[11]), 2))) + (Pow((7.44) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((16.8118) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.7) - (input[4]), 2))) + (Pow((5.277) - (input[5]), 2))) + (Pow((98.1) - (input[6]), 2))) + (Pow((1.4261) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((30.81) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.31533) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((6.2) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.504) - (input[4]), 2))) + (Pow((8.266) - (input[5]), 2))) + (Pow((78.3) - (input[6]), 2))) + (Pow((2.8944) - (input[7]), 2))) + (Pow((8.0) - (input[8]), 2))) + (Pow((307.0) - (input[9]), 2))) + (Pow((17.4) - (input[10]), 2))) + (Pow((385.05) - (input[11]), 2))) + (Pow((4.14) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((67.9208) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((5.683) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.4254) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((384.97) - (input[11]), 2))) + (Pow((22.98) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.18337) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((27.74) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.609) - (input[4]), 2))) + (Pow((5.414) - (input[5]), 2))) + (Pow((98.3) - (input[6]), 2))) + (Pow((1.7554) - (input[7]), 2))) + (Pow((4.0) - (input[8]), 2))) + (Pow((711.0) - (input[9]), 2))) + (Pow((20.1) - (input[10]), 2))) + (Pow((344.05) - (input[11]), 2))) + (Pow((23.97) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((14.3337) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.7) - (input[4]), 2))) + (Pow((4.88) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.5895) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((372.92) - (input[11]), 2))) + (Pow((30.62) - (input[12]), 2))))) * (-0.3179880503820858))) + ((Exp((var0) * (((((((((((((Pow((0.20746) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((27.74) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.609) - (input[4]), 2))) + (Pow((5.093) - (input[5]), 2))) + (Pow((98.0) - (input[6]), 2))) + (Pow((1.8226) - (input[7]), 2))) + (Pow((4.0) - (input[8]), 2))) + (Pow((711.0) - (input[9]), 2))) + (Pow((20.1) - (input[10]), 2))) + (Pow((318.43) - (input[11]), 2))) + (Pow((29.68) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((41.5292) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((5.531) - (input[5]), 2))) + (Pow((85.4) - (input[6]), 2))) + (Pow((1.6074) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((329.46) - (input[11]), 2))) + (Pow((27.38) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((1.51902) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((19.58) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.605) - (input[4]), 2))) + (Pow((8.375) - (input[5]), 2))) + (Pow((93.9) - (input[6]), 2))) + (Pow((2.162) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((403.0) - (input[9]), 2))) + (Pow((14.7) - (input[10]), 2))) + (Pow((388.45) - (input[11]), 2))) + (Pow((3.32) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((11.5779) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.7) - (input[4]), 2))) + (Pow((5.036) - (input[5]), 2))) + (Pow((97.0) - (input[6]), 2))) + (Pow((1.77) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((25.68) - (input[12]), 2))))) * (-0.7698794401926943))) + ((Exp((var0) * (((((((((((((Pow((14.2362) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((6.343) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.5741) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((20.32) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((9.2323) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.631) - (input[4]), 2))) + (Pow((6.216) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.1691) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((366.15) - (input[11]), 2))) + (Pow((9.53) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((9.91655) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((5.852) - (input[5]), 2))) + (Pow((77.8) - (input[6]), 2))) + (Pow((1.5004) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((338.16) - (input[11]), 2))) + (Pow((29.97) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((22.0511) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.74) - (input[4]), 2))) + (Pow((5.818) - (input[5]), 2))) + (Pow((92.4) - (input[6]), 2))) + (Pow((1.8662) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((391.45) - (input[11]), 2))) + (Pow((22.11) - (input[12]), 2))))) * (-0.017541052270521836))) + ((Exp((var0) * (((((((((((((Pow((0.61154) - (input[0]), 2)) + (Pow((20.0) - (input[1]), 2))) + (Pow((3.97) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.647) - (input[4]), 2))) + (Pow((8.704) - (input[5]), 2))) + (Pow((86.9) - (input[6]), 2))) + (Pow((1.801) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((264.0) - (input[9]), 2))) + (Pow((13.0) - (input[10]), 2))) + (Pow((389.7) - (input[11]), 2))) + (Pow((5.12) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((10.8342) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.679) - (input[4]), 2))) + (Pow((6.782) - (input[5]), 2))) + (Pow((90.8) - (input[6]), 2))) + (Pow((1.8195) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((21.57) - (input[11]), 2))) + (Pow((25.79) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((15.8603) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.679) - (input[4]), 2))) + (Pow((5.896) - (input[5]), 2))) + (Pow((95.4) - (input[6]), 2))) + (Pow((1.9096) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((7.68) - (input[11]), 2))) + (Pow((24.39) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((17.8667) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.671) - (input[4]), 2))) + (Pow((6.223) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.3861) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((393.74) - (input[11]), 2))) + (Pow((21.78) - (input[12]), 2))))) * (-0.17127153707291753))) + ((Exp((var0) * (((((((((((((Pow((8.26725) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.668) - (input[4]), 2))) + (Pow((5.875) - (input[5]), 2))) + (Pow((89.6) - (input[6]), 2))) + (Pow((1.1296) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((347.88) - (input[11]), 2))) + (Pow((8.88) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((0.52693) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((6.2) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.504) - (input[4]), 2))) + (Pow((8.725) - (input[5]), 2))) + (Pow((83.0) - (input[6]), 2))) + (Pow((2.8944) - (input[7]), 2))) + (Pow((8.0) - (input[8]), 2))) + (Pow((307.0) - (input[9]), 2))) + (Pow((17.4) - (input[10]), 2))) + (Pow((382.0) - (input[11]), 2))) + (Pow((4.63) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((0.0351) - (input[0]), 2)) + (Pow((95.0) - (input[1]), 2))) + (Pow((2.68) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.4161) - (input[4]), 2))) + (Pow((7.853) - (input[5]), 2))) + (Pow((33.2) - (input[6]), 2))) + (Pow((5.118) - (input[7]), 2))) + (Pow((4.0) - (input[8]), 2))) + (Pow((224.0) - (input[9]), 2))) + (Pow((14.7) - (input[10]), 2))) + (Pow((392.78) - (input[11]), 2))) + (Pow((3.81) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((12.2472) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.584) - (input[4]), 2))) + (Pow((5.837) - (input[5]), 2))) + (Pow((59.7) - (input[6]), 2))) + (Pow((1.9976) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((24.65) - (input[11]), 2))) + (Pow((15.69) - (input[12]), 2))))) * (-0.31798805038208666))) + ((Exp((var0) * (((((((((((((Pow((14.4208) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.74) - (input[4]), 2))) + (Pow((6.461) - (input[5]), 2))) + (Pow((93.3) - (input[6]), 2))) + (Pow((2.0026) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((27.49) - (input[11]), 2))) + (Pow((18.05) - (input[12]), 2))))) * (-0.9183413019645936))) + ((Exp((var0) * (((((((((((((Pow((0.29819) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((6.2) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.504) - (input[4]), 2))) + (Pow((7.686) - (input[5]), 2))) + (Pow((17.0) - (input[6]), 2))) + (Pow((3.3751) - (input[7]), 2))) + (Pow((8.0) - (input[8]), 2))) + (Pow((307.0) - (input[9]), 2))) + (Pow((17.4) - (input[10]), 2))) + (Pow((377.51) - (input[11]), 2))) + (Pow((3.92) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((38.3518) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.693) - (input[4]), 2))) + (Pow((5.453) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.4896) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((30.59) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.06129) - (input[0]), 2)) + (Pow((20.0) - (input[1]), 2))) + (Pow((3.33) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.4429) - (input[4]), 2))) + (Pow((7.645) - (input[5]), 2))) + (Pow((49.7) - (input[6]), 2))) + (Pow((5.2119) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((216.0) - (input[9]), 2))) + (Pow((14.9) - (input[10]), 2))) + (Pow((377.07) - (input[11]), 2))) + (Pow((3.01) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((88.9762) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.671) - (input[4]), 2))) + (Pow((6.968) - (input[5]), 2))) + (Pow((91.9) - (input[6]), 2))) + (Pow((1.4165) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((396.9) - (input[11]), 2))) + (Pow((17.21) - (input[12]), 2))))) * (-0.11849528386764341))) + ((Exp((var0) * (((((((((((((Pow((0.05602) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((2.46) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.488) - (input[4]), 2))) + (Pow((7.831) - (input[5]), 2))) + (Pow((53.6) - (input[6]), 2))) + (Pow((3.1992) - (input[7]), 2))) + (Pow((3.0) - (input[8]), 2))) + (Pow((193.0) - (input[9]), 2))) + (Pow((17.8) - (input[10]), 2))) + (Pow((392.63) - (input[11]), 2))) + (Pow((4.45) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((0.01501) - (input[0]), 2)) + (Pow((90.0) - (input[1]), 2))) + (Pow((1.21) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.401) - (input[4]), 2))) + (Pow((7.923) - (input[5]), 2))) + (Pow((24.8) - (input[6]), 2))) + (Pow((5.885) - (input[7]), 2))) + (Pow((1.0) - (input[8]), 2))) + (Pow((198.0) - (input[9]), 2))) + (Pow((13.6) - (input[10]), 2))) + (Pow((395.52) - (input[11]), 2))) + (Pow((3.16) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((0.02009) - (input[0]), 2)) + (Pow((95.0) - (input[1]), 2))) + (Pow((2.68) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.4161) - (input[4]), 2))) + (Pow((8.034) - (input[5]), 2))) + (Pow((31.9) - (input[6]), 2))) + (Pow((5.118) - (input[7]), 2))) + (Pow((4.0) - (input[8]), 2))) + (Pow((224.0) - (input[9]), 2))) + (Pow((14.7) - (input[10]), 2))) + (Pow((390.55) - (input[11]), 2))) + (Pow((2.88) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((15.1772) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.74) - (input[4]), 2))) + (Pow((6.152) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.9142) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((9.32) - (input[11]), 2))) + (Pow((26.45) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((18.0846) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.679) - (input[4]), 2))) + (Pow((6.434) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.8347) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((27.25) - (input[11]), 2))) + (Pow((29.05) - (input[12]), 2))))) * (-1.0))) + ((Exp((var0) * (((((((((((((Pow((0.01381) - (input[0]), 2)) + (Pow((80.0) - (input[1]), 2))) + (Pow((0.46) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.422) - (input[4]), 2))) + (Pow((7.875) - (input[5]), 2))) + (Pow((32.0) - (input[6]), 2))) + (Pow((5.6484) - (input[7]), 2))) + (Pow((4.0) - (input[8]), 2))) + (Pow((255.0) - (input[9]), 2))) + (Pow((14.4) - (input[10]), 2))) + (Pow((394.23) - (input[11]), 2))) + (Pow((2.97) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((5.66998) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((1.0) - (input[3]), 2))) + (Pow((0.631) - (input[4]), 2))) + (Pow((6.683) - (input[5]), 2))) + (Pow((96.8) - (input[6]), 2))) + (Pow((1.3567) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((375.33) - (input[11]), 2))) + (Pow((3.73) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((0.01538) - (input[0]), 2)) + (Pow((90.0) - (input[1]), 2))) + (Pow((3.75) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.394) - (input[4]), 2))) + (Pow((7.454) - (input[5]), 2))) + (Pow((34.2) - (input[6]), 2))) + (Pow((6.3361) - (input[7]), 2))) + (Pow((3.0) - (input[8]), 2))) + (Pow((244.0) - (input[9]), 2))) + (Pow((15.9) - (input[10]), 2))) + (Pow((386.34) - (input[11]), 2))) + (Pow((3.11) - (input[12]), 2))))) * (0.47499999996189857))) + ((Exp((var0) * (((((((((((((Pow((4.89822) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.631) - (input[4]), 2))) + (Pow((4.97) - (input[5]), 2))) + (Pow((100.0) - (input[6]), 2))) + (Pow((1.3325) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((375.52) - (input[11]), 2))) + (Pow((3.26) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((2.01019) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((19.58) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.605) - (input[4]), 2))) + (Pow((7.929) - (input[5]), 2))) + (Pow((96.2) - (input[6]), 2))) + (Pow((2.0459) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((403.0) - (input[9]), 2))) + (Pow((14.7) - (input[10]), 2))) + (Pow((369.3) - (input[11]), 2))) + (Pow((3.7) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((0.52014) - (input[0]), 2)) + (Pow((20.0) - (input[1]), 2))) + (Pow((3.97) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.647) - (input[4]), 2))) + (Pow((8.398) - (input[5]), 2))) + (Pow((91.5) - (input[6]), 2))) + (Pow((2.2885) - (input[7]), 2))) + (Pow((5.0) - (input[8]), 2))) + (Pow((264.0) - (input[9]), 2))) + (Pow((13.0) - (input[10]), 2))) + (Pow((386.86) - (input[11]), 2))) + (Pow((5.91) - (input[12]), 2))))) * (1.0))) + ((Exp((var0) * (((((((((((((Pow((9.33889) - (input[0]), 2)) + (Pow((0.0) - (input[1]), 2))) + (Pow((18.1) - (input[2]), 2))) + (Pow((0.0) - (input[3]), 2))) + (Pow((0.679) - (input[4]), 2))) + (Pow((6.38) - (input[5]), 2))) + (Pow((95.6) - (input[6]), 2))) + (Pow((1.9682) - (input[7]), 2))) + (Pow((24.0) - (input[8]), 2))) + (Pow((666.0) - (input[9]), 2))) + (Pow((20.2) - (input[10]), 2))) + (Pow((60.72) - (input[11]), 2))) + (Pow((24.08) - (input[12]), 2))))) * (-1.0));
+        }
+    }
+}
diff --git a/generated_code_examples/c_sharp/regression/xgboost.cs b/generated_code_examples/c_sharp/regression/xgboost.cs
new file mode 100644
index 00000000..1b960bf0
--- /dev/null
+++ b/generated_code_examples/c_sharp/regression/xgboost.cs
@@ -0,0 +1,35 @@
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            if ((input[12]) >= (9.72500038)) {
+                if ((input[12]) >= (19.8299999)) {
+                    var0 = 1.1551429;
+                } else {
+                    var0 = 1.8613131;
+                }
+            } else {
+                if ((input[5]) >= (6.94099998)) {
+                    var0 = 3.75848508;
+                } else {
+                    var0 = 2.48056006;
+                }
+            }
+            double var1;
+            if ((input[12]) >= (7.68499994)) {
+                if ((input[12]) >= (15)) {
+                    var1 = 1.24537706;
+                } else {
+                    var1 = 1.92129695;
+                }
+            } else {
+                if ((input[5]) >= (7.43700027)) {
+                    var1 = 3.96021533;
+                } else {
+                    var1 = 2.51493931;
+                }
+            }
+            return ((0.5) + (var0)) + (var1);
+        }
+    }
+}
diff --git a/m2cgen/__init__.py b/m2cgen/__init__.py
index 8e49a7e6..c0aa1e3c 100644
--- a/m2cgen/__init__.py
+++ b/m2cgen/__init__.py
@@ -7,6 +7,7 @@
     export_to_python,
     export_to_javascript,
     export_to_visual_basic,
+    export_to_c_sharp,
 )
 
 __all__ = [
@@ -16,6 +17,7 @@
     export_to_go,
     export_to_javascript,
     export_to_visual_basic,
+    export_to_c_sharp,
 ]
 
 with open(os.path.join(os.path.dirname(os.path.realpath(__file__)),
diff --git a/m2cgen/cli.py b/m2cgen/cli.py
index f9d1701e..e8cbb89b 100644
--- a/m2cgen/cli.py
+++ b/m2cgen/cli.py
@@ -24,6 +24,8 @@
     "javascript": (m2cgen.export_to_javascript, ["indent"]),
     "visual_basic": (m2cgen.export_to_visual_basic,
                      ["module_name", "indent"]),
+    "c_sharp": (m2cgen.export_to_c_sharp,
+                ["indent", "class_name", "namespace"]),
 }
 
 
@@ -54,6 +56,10 @@
     "--module_name", "-mn", dest="module_name", type=str,
     help="Module name for the generated code "
          "(if supported by target language)")
+parser.add_argument(
+    "--namespace", "-ns", dest="namespace", type=str,
+    help="Namespace for the generated code "
+         "(if supported by target language)")
 parser.add_argument(
     "--indent", "-i", dest="indent", type=int,
     default=4,
diff --git a/m2cgen/exporters.py b/m2cgen/exporters.py
index 0418a413..d467a599 100644
--- a/m2cgen/exporters.py
+++ b/m2cgen/exporters.py
@@ -168,6 +168,32 @@ def export_to_visual_basic(model, module_name="Model", indent=4):
     return _export(model, interpreter)
 
 
+def export_to_c_sharp(model, namespace="ML", class_name="Model", indent=4):
+    """
+    Generates a C# code representation of the given model.
+
+    Parameters
+    ----------
+    model : object
+        The model object that should be transpiled into code.
+    namespace : string, optional
+        The namespace for the generated code.
+    class_name : string, optional
+        The name of the generated class.
+    indent : int, optional
+        The size of indents in the generated code.
+
+    Returns
+    -------
+    code : string
+    """
+    interpreter = interpreters.CSharpInterpreter(
+        namespace=namespace,
+        class_name=class_name,
+        indent=indent)
+    return _export(model, interpreter)
+
+
 def _export(model, interpreter):
     assembler_cls = assemblers.get_assembler_cls(model)
     model_ast = assembler_cls(model).assemble()
diff --git a/m2cgen/interpreters/__init__.py b/m2cgen/interpreters/__init__.py
index fb713e4b..7bc80053 100644
--- a/m2cgen/interpreters/__init__.py
+++ b/m2cgen/interpreters/__init__.py
@@ -4,6 +4,7 @@
 from .go.interpreter import GoInterpreter
 from .javascript.interpreter import JavascriptInterpreter
 from .visual_basic.interpreter import VisualBasicInterpreter
+from .c_sharp.interpreter import CSharpInterpreter
 
 __all__ = [
     JavaInterpreter,
@@ -12,4 +13,5 @@
     GoInterpreter,
     JavascriptInterpreter,
     VisualBasicInterpreter,
+    CSharpInterpreter,
 ]
diff --git a/m2cgen/interpreters/c_sharp/__init__.py b/m2cgen/interpreters/c_sharp/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/m2cgen/interpreters/c_sharp/code_generator.py b/m2cgen/interpreters/c_sharp/code_generator.py
new file mode 100644
index 00000000..502449b3
--- /dev/null
+++ b/m2cgen/interpreters/c_sharp/code_generator.py
@@ -0,0 +1,65 @@
+import contextlib
+
+from m2cgen.interpreters.code_generator import CLikeCodeGenerator
+
+
+class CSharpCodeGenerator(CLikeCodeGenerator):
+
+    scalar_type = "double"
+    vector_type = "double[]"
+
+    def __init__(self, *args, **kwargs):
+        super(CSharpCodeGenerator, self).__init__(*args, **kwargs)
+
+    def add_class_def(self, class_name, modifier="public"):
+        class_def = modifier + " static class " + class_name + " {"
+        self.add_code_line(class_def)
+        self.increase_indent()
+
+    def add_method_def(self, name, args, is_vector_output,
+                       modifier="private"):
+        return_type = self._get_var_declare_type(is_vector_output)
+        method_def = modifier + " static " + return_type + " " + name + "("
+        method_def += ",".join([
+            self._get_var_declare_type(is_vector) + " " + n
+            for is_vector, n in args])
+        method_def += ") {"
+        self.add_code_line(method_def)
+        self.increase_indent()
+
+    def add_namespace_def(self, namespace):
+        namespace_def = "namespace " + namespace + " {"
+        self.add_code_line(namespace_def)
+        self.increase_indent()
+
+    @contextlib.contextmanager
+    def class_definition(self, class_name, modifier="public"):
+        self.add_class_def(class_name, modifier=modifier)
+        yield
+        self.add_block_termination()
+
+    @contextlib.contextmanager
+    def method_definition(self, name, args, is_vector_output,
+                          modifier="private"):
+        self.add_method_def(name, args, is_vector_output, modifier=modifier)
+        yield
+        self.add_block_termination()
+
+    @contextlib.contextmanager
+    def namespace_definition(self, namespace):
+        self.add_namespace_def(namespace)
+        yield
+        self.add_block_termination()
+
+    def vector_init(self, values):
+        return ("new double[{}] {{".format(len(values)) +
+                ", ".join(values) + "}")
+
+    def _get_var_declare_type(self, is_vector):
+        return (
+            self.vector_type if is_vector
+            else self.scalar_type)
+
+    def add_dependency(self, dep, modifier="static"):
+        dep_str = "using {0} {1};".format(modifier, dep)
+        self.prepend_code_line(dep_str)
diff --git a/m2cgen/interpreters/c_sharp/interpreter.py b/m2cgen/interpreters/c_sharp/interpreter.py
new file mode 100644
index 00000000..f7d52909
--- /dev/null
+++ b/m2cgen/interpreters/c_sharp/interpreter.py
@@ -0,0 +1,58 @@
+import os
+
+from m2cgen import ast
+from m2cgen.interpreters import mixins
+from m2cgen.interpreters import utils
+from m2cgen.interpreters.interpreter import ToCodeInterpreter
+from m2cgen.interpreters.c_sharp.code_generator import CSharpCodeGenerator
+
+
+class CSharpInterpreter(ToCodeInterpreter, mixins.LinearAlgebraMixin):
+
+    supported_bin_vector_ops = {
+        ast.BinNumOpType.ADD: "AddVectors",
+    }
+
+    supported_bin_vector_num_ops = {
+        ast.BinNumOpType.MUL: "MulVectorNumber",
+    }
+
+    exponent_function_name = "Exp"
+    power_function_name = "Pow"
+    tanh_function_name = "Tanh"
+
+    def __init__(self, namespace="ML", class_name="Model", indent=4,
+                 *args, **kwargs):
+        self.namespace = namespace
+        self.class_name = class_name
+        self.indent = indent
+
+        cg = CSharpCodeGenerator(indent=indent)
+        super(CSharpInterpreter, self).__init__(cg, *args, **kwargs)
+
+    def interpret(self, expr):
+        self._cg.reset_state()
+        self._reset_reused_expr_cache()
+
+        method_name = "Score"
+        args = [(True, self._feature_array_name)]
+
+        with self._cg.namespace_definition(self.namespace):
+            with self._cg.class_definition(self.class_name):
+                with self._cg.method_definition(
+                        name=method_name,
+                        args=args,
+                        is_vector_output=expr.output_size > 1,
+                        modifier="public"):
+                    last_result = self._do_interpret(expr)
+                    self._cg.add_return_statement(last_result)
+
+                if self.with_linear_algebra:
+                    filename = os.path.join(
+                        os.path.dirname(__file__), "linear_algebra.cs")
+                    self._cg.add_code_lines(utils.get_file_content(filename))
+
+        if self.with_math_module:
+            self._cg.add_dependency("System.Math")
+
+        return self._cg.code
diff --git a/m2cgen/interpreters/c_sharp/linear_algebra.cs b/m2cgen/interpreters/c_sharp/linear_algebra.cs
new file mode 100644
index 00000000..0147e04c
--- /dev/null
+++ b/m2cgen/interpreters/c_sharp/linear_algebra.cs
@@ -0,0 +1,14 @@
+private static double[] AddVectors(double[] v1, double[] v2) {
+    double[] result = new double[v1.Length];
+    for (int i = 0; i < v1.Length; ++i) {
+        result[i] = v1[i] + v2[i];
+    }
+    return result;
+}
+private static double[] MulVectorNumber(double[] v1, double num) {
+    double[] result = new double[v1.Length];
+    for (int i = 0; i < v1.Length; ++i) {
+        result[i] = v1[i] * num;
+    }
+    return result;
+}
diff --git a/tools/generate_code_examples.py b/tools/generate_code_examples.py
index 6c6c30a9..bc833f8d 100644
--- a/tools/generate_code_examples.py
+++ b/tools/generate_code_examples.py
@@ -38,6 +38,7 @@
     ("go", m2c.export_to_go, "go"),
     ("javascript", m2c.export_to_javascript, "js"),
     ("visual_basic", m2c.export_to_visual_basic, "vb"),
+    ("c_sharp", m2c.export_to_c_sharp, "cs"),
 ]
 
 EXAMPLE_MODELS = [


Test patch:
diff --git a/tests/e2e/executors/__init__.py b/tests/e2e/executors/__init__.py
index cf5eb443..449b9d8d 100644
--- a/tests/e2e/executors/__init__.py
+++ b/tests/e2e/executors/__init__.py
@@ -4,6 +4,7 @@
 from tests.e2e.executors.go import GoExecutor
 from tests.e2e.executors.javascript import JavascriptExecutor
 from tests.e2e.executors.visual_basic import VisualBasicExecutor
+from tests.e2e.executors.c_sharp import CSharpExecutor
 
 __all__ = [
     JavaExecutor,
@@ -12,4 +13,5 @@
     GoExecutor,
     JavascriptExecutor,
     VisualBasicExecutor,
+    CSharpExecutor,
 ]
diff --git a/tests/e2e/executors/c_sharp.py b/tests/e2e/executors/c_sharp.py
new file mode 100644
index 00000000..c59fe667
--- /dev/null
+++ b/tests/e2e/executors/c_sharp.py
@@ -0,0 +1,93 @@
+import os
+import string
+import subprocess
+
+from m2cgen import assemblers, interpreters
+from tests import utils
+from tests.e2e.executors import base
+
+EXECUTOR_CODE_TPL = """
+using System;
+
+namespace TestConsoleApp {
+    class Program {
+        static void Main(string[] args) {
+            double[] input_ = new double[args.Length];
+            for(int i = 0; i < input_.Length; ++i) {
+                input_[i] = double.Parse(args[i]);
+            }
+            ${print_code}
+        }
+    }
+}
+"""
+
+EXECUTE_AND_PRINT_SCALAR = """
+            double res = ML.Model.Score(input_);
+            Console.Write(res);
+"""
+
+EXECUTE_AND_PRINT_VECTOR = """
+            double[] res = ML.Model.Score(input_);
+            for(int i = 0; i < res.Length; ++i) {
+                Console.Write("{0} ", res[i]);
+            }
+"""
+
+
+class CSharpExecutor(base.BaseExecutor):
+
+    target_exec_dir = None
+    project_name = "test_model"
+    _dotnet = "dotnet"
+
+    def __init__(self, model):
+        self.model = model
+        self.interpreter = interpreters.CSharpInterpreter()
+
+        assembler_cls = assemblers.get_assembler_cls(model)
+        self.model_ast = assembler_cls(model).assemble()
+
+    def predict(self, X):
+        exec_args = [os.path.join(self.target_exec_dir, self.project_name)]
+        exec_args.extend(map(str, X))
+        return utils.predict_from_commandline(exec_args)
+
+    @classmethod
+    def prepare_global(cls, **kwargs):
+        super(CSharpExecutor, cls).prepare_global(**kwargs)
+        if cls.target_exec_dir is None:
+            cls.target_exec_dir = os.path.join(cls._global_tmp_dir, "bin")
+
+            subprocess.call([cls._dotnet,
+                             "new",
+                             "console",
+                             "--output",
+                             cls._global_tmp_dir,
+                             "--name",
+                             cls.project_name,
+                             "--language",
+                             "C#"])
+
+    def prepare(self):
+        if self.model_ast.output_size > 1:
+            print_code = EXECUTE_AND_PRINT_VECTOR
+        else:
+            print_code = EXECUTE_AND_PRINT_SCALAR
+        executor_code = string.Template(EXECUTOR_CODE_TPL).substitute(
+            print_code=print_code)
+        model_code = self.interpreter.interpret(self.model_ast)
+
+        model_file_name = os.path.join(self._global_tmp_dir, "Model.cs")
+        executor_file_name = os.path.join(self._global_tmp_dir, "Program.cs")
+        with open(model_file_name, "w") as f:
+            f.write(model_code)
+        with open(executor_file_name, "w") as f:
+            f.write(executor_code)
+
+        subprocess.call([self._dotnet,
+                         "build",
+                         os.path.join(self._global_tmp_dir,
+                                      "{}.csproj".format(self.project_name)),
+                         "--output",
+                         self.target_exec_dir])
diff --git a/tests/e2e/test_e2e.py b/tests/e2e/test_e2e.py
index 2cf7db65..8b64bb4a 100644
--- a/tests/e2e/test_e2e.py
+++ b/tests/e2e/test_e2e.py
@@ -21,6 +21,7 @@
 GO = pytest.mark.go
 JAVASCRIPT = pytest.mark.javascript
 VISUAL_BASIC = pytest.mark.visual_basic
+C_SHARP = pytest.mark.c_sharp
 REGRESSION = pytest.mark.regr
 CLASSIFICATION = pytest.mark.clf
 
@@ -73,6 +74,7 @@ def classification_binary(model):
         (executors.GoExecutor, GO),
         (executors.JavascriptExecutor, JAVASCRIPT),
         (executors.VisualBasicExecutor, VISUAL_BASIC),
+        (executors.CSharpExecutor, C_SHARP),
     ],
 
     # These models will be tested against each language specified in the
diff --git a/tests/interpreters/test_c_sharp.py b/tests/interpreters/test_c_sharp.py
new file mode 100644
index 00000000..c59e186a
--- /dev/null
+++ b/tests/interpreters/test_c_sharp.py
@@ -0,0 +1,369 @@
+from m2cgen import ast
+from m2cgen.interpreters import CSharpInterpreter
+from tests import utils
+
+
+def test_if_expr():
+    expr = ast.IfExpr(
+        ast.CompExpr(ast.NumVal(1), ast.FeatureRef(0), ast.CompOpType.EQ),
+        ast.NumVal(2),
+        ast.NumVal(3))
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            if ((1) == (input[0])) {
+                var0 = 2;
+            } else {
+                var0 = 3;
+            }
+            return var0;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_bin_num_expr():
+    expr = ast.BinNumExpr(
+        ast.BinNumExpr(
+            ast.FeatureRef(0), ast.NumVal(-2), ast.BinNumOpType.DIV),
+        ast.NumVal(2),
+        ast.BinNumOpType.MUL)
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            return ((input[0]) / (-2)) * (2);
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_dependable_condition():
+    left = ast.BinNumExpr(
+        ast.IfExpr(
+            ast.CompExpr(ast.NumVal(1),
+                         ast.NumVal(1),
+                         ast.CompOpType.EQ),
+            ast.NumVal(1),
+            ast.NumVal(2)),
+        ast.NumVal(2),
+        ast.BinNumOpType.ADD)
+
+    right = ast.BinNumExpr(ast.NumVal(1), ast.NumVal(2), ast.BinNumOpType.DIV)
+    bool_test = ast.CompExpr(left, right, ast.CompOpType.GTE)
+
+    expr = ast.IfExpr(bool_test, ast.NumVal(1), ast.FeatureRef(0))
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            double var1;
+            if ((1) == (1)) {
+                var1 = 1;
+            } else {
+                var1 = 2;
+            }
+            if (((var1) + (2)) >= ((1) / (2))) {
+                var0 = 1;
+            } else {
+                var0 = input[0];
+            }
+            return var0;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_nested_condition():
+    left = ast.BinNumExpr(
+        ast.IfExpr(
+            ast.CompExpr(ast.NumVal(1),
+                         ast.NumVal(1),
+                         ast.CompOpType.EQ),
+            ast.NumVal(1),
+            ast.NumVal(2)),
+        ast.NumVal(2),
+        ast.BinNumOpType.ADD)
+
+    bool_test = ast.CompExpr(ast.NumVal(1), left, ast.CompOpType.EQ)
+
+    expr_nested = ast.IfExpr(bool_test, ast.FeatureRef(2), ast.NumVal(2))
+
+    expr = ast.IfExpr(bool_test, expr_nested, ast.NumVal(2))
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            double var1;
+            if ((1) == (1)) {
+                var1 = 1;
+            } else {
+                var1 = 2;
+            }
+            if ((1) == ((var1) + (2))) {
+                double var2;
+                if ((1) == (1)) {
+                    var2 = 1;
+                } else {
+                    var2 = 2;
+                }
+                if ((1) == ((var2) + (2))) {
+                    var0 = input[2];
+                } else {
+                    var0 = 2;
+                }
+            } else {
+                var0 = 2;
+            }
+            return var0;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_namespace():
+    expr = ast.NumVal(1)
+
+    expected_code = """
+namespace ML.Tests {
+    public static class Model {
+        public static double Score(double[] input) {
+            return 1;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter(namespace="ML.Tests")
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_class_name():
+    expr = ast.NumVal(1)
+
+    expected_code = """
+namespace ML {
+    public static class TestModel {
+        public static double Score(double[] input) {
+            return 1;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter(class_name="TestModel")
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_raw_array():
+    expr = ast.VectorVal([ast.NumVal(3), ast.NumVal(4)])
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            return new double[2] {3, 4};
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_multi_output():
+    expr = ast.SubroutineExpr(
+        ast.IfExpr(
+            ast.CompExpr(
+                ast.NumVal(1),
+                ast.NumVal(1),
+                ast.CompOpType.EQ),
+            ast.VectorVal([ast.NumVal(1), ast.NumVal(2)]),
+            ast.VectorVal([ast.NumVal(3), ast.NumVal(4)])))
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            double[] var0;
+            if ((1) == (1)) {
+                var0 = new double[2] {1, 2};
+            } else {
+                var0 = new double[2] {3, 4};
+            }
+            return var0;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_bin_vector_expr():
+    expr = ast.BinVectorExpr(
+        ast.VectorVal([ast.NumVal(1), ast.NumVal(2)]),
+        ast.VectorVal([ast.NumVal(3), ast.NumVal(4)]),
+        ast.BinNumOpType.ADD)
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            return AddVectors(new double[2] {1, 2}, new double[2] {3, 4});
+        }
+        private static double[] AddVectors(double[] v1, double[] v2) {
+            double[] result = new double[v1.Length];
+            for (int i = 0; i < v1.Length; ++i) {
+                result[i] = v1[i] + v2[i];
+            }
+            return result;
+        }
+        private static double[] MulVectorNumber(double[] v1, double num) {
+            double[] result = new double[v1.Length];
+            for (int i = 0; i < v1.Length; ++i) {
+                result[i] = v1[i] * num;
+            }
+            return result;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_bin_vector_num_expr():
+    expr = ast.BinVectorNumExpr(
+        ast.VectorVal([ast.NumVal(1), ast.NumVal(2)]),
+        ast.NumVal(1),
+        ast.BinNumOpType.MUL)
+
+    expected_code = """
+namespace ML {
+    public static class Model {
+        public static double[] Score(double[] input) {
+            return MulVectorNumber(new double[2] {1, 2}, 1);
+        }
+        private static double[] AddVectors(double[] v1, double[] v2) {
+            double[] result = new double[v1.Length];
+            for (int i = 0; i < v1.Length; ++i) {
+                result[i] = v1[i] + v2[i];
+            }
+            return result;
+        }
+        private static double[] MulVectorNumber(double[] v1, double num) {
+            double[] result = new double[v1.Length];
+            for (int i = 0; i < v1.Length; ++i) {
+                result[i] = v1[i] * num;
+            }
+            return result;
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_exp_expr():
+    expr = ast.ExpExpr(ast.NumVal(1.0))
+
+    expected_code = """
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            return Exp(1.0);
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_pow_expr():
+    expr = ast.PowExpr(ast.NumVal(2.0), ast.NumVal(3.0))
+
+    expected_code = """
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            return Pow(2.0, 3.0);
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_tanh_expr():
+    expr = ast.TanhExpr(ast.NumVal(2.0))
+
+    expected_code = """
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            return Tanh(2.0);
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
+
+
+def test_reused_expr():
+    reused_expr = ast.ExpExpr(ast.NumVal(1.0), to_reuse=True)
+    expr = ast.BinNumExpr(reused_expr, reused_expr, ast.BinNumOpType.DIV)
+
+    expected_code = """
+using static System.Math;
+namespace ML {
+    public static class Model {
+        public static double Score(double[] input) {
+            double var0;
+            var0 = Exp(1.0);
+            return (var0) / (var0);
+        }
+    }
+}
+"""
+
+    interpreter = CSharpInterpreter()
+    utils.assert_code_equal(interpreter.interpret(expr), expected_code)
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 6663c22b..296ba55d 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -10,11 +10,13 @@
 from tests import utils
 
 
-def _get_mock_args(indent=4, module_name=None, package_name=None,
-                   class_name=None, infile=None, language=None):
+def _get_mock_args(indent=4, namespace=None, module_name=None,
+                   package_name=None, class_name=None,
+                   infile=None, language=None):
     return mock.MagicMock(
-        indent=indent, module_name=module_name, package_name=package_name,
-        class_name=class_name, infile=infile, language=language,
+        indent=indent, namespace=namespace, module_name=module_name,
+        package_name=package_name, class_name=class_name,
+        infile=infile, language=language,
         recursion_limit=cli.MAX_RECURSION_DEPTH)
 
 
@@ -114,6 +116,16 @@ def test_module_name():
     assert generated_code.startswith("Module TestModule")
 
 
+def test_namespace():
+    infile = _get_pickled_trained_model()
+    mock_args = _get_mock_args(
+        infile=infile, language="c_sharp", namespace="Tests.ML")
+
+    generated_code = cli.generate_code(mock_args).strip()
+
+    assert generated_code.find("namespace Tests.ML {") != -1
+
+
 def test_unsupported_args_are_ignored():
     infile = _get_pickled_trained_model()