Home PC Games Linux Windows Database Network Programming Server Mobile  
  Home \ Programming \ C # compiler to achieve functional use in the runtime     - How to protect your eyes automatically adjust the screen brightness on Linux (Linux)

- Linux system started to learn: how to view the contents of the seed on the Linux file (Linux)

- Python 2 Chinese garbage problem solved (Linux)

- The Hill sorting algorithm (Programming)

- Hyper-V virtual hard disk how to copy files to and attached to the virtual machine (Linux)

- UNIX and class UNIX system security check notes (Linux)

- iOS development -Launch Image and Launchscreen (Programming)

- GitHub multiplayer co-development configuration (Linux)

- Oracle database file path changes (Database)

- Analyzing Linux server architecture is 32-bit / 64-bit (Server)

- Java polymorphism and exception handling (Programming)

- What happens after the MySQL disk space is full (Database)

- HDFS Distributed File System Resource Manager Developer summary (Server)

- Broadcom transplanted to OpenWrt summary (Programming)

- Management Linux Container with Docker in Ubuntu (Linux)

- To install minimize RHEL / CentOS 7 (Linux)

- Oracle Shared Server Configuration (Database)

- How to run Docker client in Windows operating system (Linux)

- How to Upgrade Ubuntu GNOME 14.10 to GNOME 3.16 Desktop (Linux)

- Ubuntu install Liferea news subscription software (Linux)

  C # compiler to achieve functional use in the runtime
  Add Date : 2018-11-21      

I want to share a new model, I developed to be used for compiling generic calculated using the run time in C #.

Over the past few years I have seen many examples in the programming and implement generic math in C #, but no one can do very well. In the first part I will be a step by step explanation of some of the examples I have seen, but also explain why they do not provide a good model to Functional.

I developed this model as part of my Seven Framework framework of the project. If you are interested, you can click on: https: //github.com/53V3N1X/SevenFramework.

Issues Overview

First, the fundamental problem is dealing with generic C #, just as in the base class. In addition System.Object base class, they have no implicit members. That is, with respect to the standard numeric types (int, double, decimal, etc.) they do not have arithmetic operators and implicit conversions. EXAMPLE 1 is an ideal situation, but in standard C # code is not compiled.

// EXAMPLE 1 ----------------------------------------
namespace ConsoleApplication
{Public class Program
    {Public static void Main (string [] args)
      {Sum < int> (new int [] {1, 2, 3, 4, 5});}
    public static T Sum < T> (T [] array)
    {T sum = 0; // (1) can not convert int to generic
        for (int i = 0; i < array.Length; i ++)
        sum + = array [i]; // (2) can not assume addition operator on generic
        return sum;}

Indeed, EXAMPLE 1 will not compile because:

Type "T" does not ensure int values implicit conversion.

Type "T" can not ensure an add operation.

Now we understand the fundamental problem, let us begin to find some way to overcome it.

Interface-based solutions

C # where clause is a generic forced to meet some type of restraint. However, this method requires to have a C # does not exist in the basic numeric types. C # there is such a basic numeric types is the closest to force numeric types may become generic, but that does not help us on mathematics. EXAMPLE 2 still can not compile, but if we create our own basic numeric types, this will be possible.

Hide Copy Code

// EXAMPLE 2 ----------------------------------------
namespace ConsoleApplication {
public class Program
public static void Main (string [] args)
Sum < int> (new int [] {1, 2, 3, 4, 5});
public static T Sum < T> (T [] array)
where T: number // (1) there is no base "number" type in C #
{T sum = 0;
for (int i = 0; i < array.Length; i ++)
sum + = array [i];
return sum;}

Now EXAMPLE 2 will not compile because:

Without basic "value" type in C #.

If we realize our own basic "value" type, you can make it compile. We are required to do is to force the numeric types have C # basic numeric types and arithmetic operators generally implicit conversions. Logically speaking, this should be an interface.

However, even if we ourselves do numerical interface, we still have a major problem. We will not be able to type in C # do basic common mathematical calculations, because we can not change int, double, decimal and other source code to implement our interface. So, we not only have to write your own basic interface, but also need to write a wrapper for the primitive types in C #.
In Example 3, we have our own values Interface, "Digital", and int primitive type wrapper, Integer32.

// EXAMPLE 3 ----------------------------------------
namespace ConsoleApplication
public class Program
public static void Main (string [] args)
Sum (new Number []
new Integer32 (1), // (1) initialization nightmares ...
new Integer32 (2),
new Integer32 (3),
new Integer32 (4),
new Integer32 (5)
public static Number Sum (Number [] array)
Number sum = array [0] .GetZero (); // (2) instance-based factory methods are terrible design
for (int i = 0; i < array.Length; i ++)
sum = sum.Add (array [i]);
return sum;
public interface Number
Number GetZero (); // (2) again ... instance based factory methods are awful
Number Add (Number other);
public struct Integer32: Number // (3) C # primitives can not implement "Number"
int _value;
public Integer32 (int value)
this._value = value;
Number Number.GetZero ()
return new Integer32 (0);
} // (4) you will have to re-write these functions for every single type
Number Number.Add (Number other)
return new Integer32 (_value + ((Integer32) other) ._ value);
} // (5) this code is incredibly slow

Okay, so EXAMPLE 3 to compile, but it is a little worse, and why:

When programming interfaces used to initialize variables is very ugly.

You should not use a constructor or factory method as an instance method, because it is a bad design and a null reference exception is likely to result in the entire program.

You can not let the C # primitive types to achieve "Number" is possible only with a custom interface to the type of work.

It is not functional because you have to write every step to achieve a custom.

This code package because the basic type of work is extremely slow.

If you can not make complete functional library in C # generics math, no one will pay for this. Therefore, let us take over in the deal with this problem. If you can not modify the C # primitive data types to achieve the desired interface, then we create another type capable of handling all types of mathematical operations that have. This is a standard widely used in .Net framework provider model.

Side note / vent: Personally, I hate provider mode. But I still have not found an example of using delegates handled properly. When a large number of create a large number of providers who do not use a delegate.

When we use the provider model is still essentially doing the same thing as before, but a provider class will be able to handle all the math. Test it in EXAMPLE 4:

/ EXAMPLE 4 ----------------------------------------
namespace ConsoleApplication
public class Program
public static void Main (string [] args)
Sum < int> (new int [] {1, 2, 3, 4, 5}, new MathProvider_int ());
} // (1) all the methods need access to the provider
public static T
Sum < T> (T [] array, MathProvider < T> mathProvider)
T sum = mathProvider.GetZero ();
for (int i = 0; i < array.Length; i ++)
sum = mathProvider.Add (sum, array [i]);
return sum;}
public interface MathProvider < T>
T GetZero (); // (2) you still need instance factory methods
T Add (T left, T right);
 public class MathProvider_int: MathProvider < int>
public MathProvider_int () {}
int MathProvider < int> .GetZero ()
return 0;
} // (3) you still have to implement each function for every single type
int MathProvider < int> .Add (int left, int right)
return left + right;
} // (4) can be slow depending on implementation (this version is slow)

EXAMPLE 4 by moving all of the functional properties of the class to help, we can use C # basic types perform mathematical operations. However, this is only repair EXMAPLE 3 in the first question. We still need to address the following issues:

All methods must access mathProvider class. Although you can write code, do not have to let it pass between each function, this principle also applies to other similar structures.

You instantiate still based factory methods. In the above case, it is a conversion from int.

You still need to achieve functional properties for each simple type in the original code.

This is still quite slow, unless you do something for the provider "smart" caching. provider delivery and look really add a lot.

Now that we have tried to use interface value type itself (EXAMPLE 3) and an external provider (EXAMPLE 4) on. Using the interface we have not done more. What is certain is that we can use some clever clever storage method, but will eventually face the same problem: custom implementation must support at every step.

The final say ... in C # interfaces are not suitable for use in an efficient functional calculations.

Object Conversion

In C #, everything can be converted to System.Object type. So, I just put every thing into an object is then used to control the flow of the process it can be. Let's try.

Hide Shrink Copy Code

// EXAMPLE 5 ----------------------------------------
namespace ConsoleApplication
public class Program
public static void Main (string [] args)
MathProvider < int> .Sum (new int [] {1, 2, 3, 4, 5});
public static class MathProvider < T>
public static T Sum (T [] array)
{// (1) still requires a custom implementation for every type
if (typeof (T) == typeof (int))
T sum = (T) (object) 0; // (2) largescale casting is very glitch prone
for (int i = 0; i < array.Length; i ++)
sum = (T) (object) ((int) (object) sum + ((int) (object) array [i]));
return sum;} t
hrow new System.Exception ( "UNSUPPORTED TYPE"); // (3) runtime errors
// (4) horribly slow ...

The fact is that it looks better than the interface method. The code is simple and easy to use. However, as before, we still have a lot of problems:

We still have to create a custom implementation for each type.

Meanwhile, we have a lot of type conversion may cause abnormal and very slow.

And do not support the types of runtime errors.

Poor performance.

Note: I do not know if they still do this in with F #, F #, but when I browse in the general standard math functions, they do look like the lowest level object conversion. Ridiculous!

Object into another dead end, but at least it is very simple to use.


Agent ...... really great!

We can not be like the original type as efficiently complete mathematical calculations. If there is no inheritance of each compiler can not make a judgment, and we can not let C # primitive types inherit our own class.

So, we put the general functionality of the code outside the class in general are removed it. We need to how to do it? proxy! As long as the general class set up a proxy, and dispensed from the outside at run time, these types can be recognized by the compiler.

However, we can delegate (proxy) into the generic class, and then assign an external compiler at run time commissioned (agent).

Hide Shrink Copy Code

// EXAMPLE 5 ----------------------------------------
namespace ConsoleApplication
public class Program
public static void Main (string [] args)
{// (1) requires a constructor method to be called prior to use
MathProviderConstructors.Construct ();
MathProvider < int> .Sum (new int [] {1, 2, 3, 4, 5});
public static class MathProviderConstructors
public static void Construct ()
// (2) still requires a custom implementation for every type
MathProvider < int> .Sum = (int [] array) =>
int sum = 0;
for (int i = 0; i < array.Length; i ++)
sum = sum + array [i];
return sum;
public static class MathProvider < T>
// (3) still have runtime errors for non-implemented types (null-ref)
public static System.Func < T [], T> Sum;
EXMAPLE 5 Functional is the best example. It runs fast, suitable for any type, and in addition to ensuring the static constructor must be called outside easy to use. However, it still has some flaws ... (1) constructor must be called, (2) for each type is still a need to implement a custom, (3) will throw a runtime error.

At this point we have to make some compromises. First, the run-time exception is almost inevitable. The only way I can think of is to make a custom plug-in is added to Visual Studio that will throw additional compilation errors. That for the purposes of this article, it is necessary to deal with the run-time exception. But the biggest problem is that we still have to write a function that we need to support each type. There must be a way to solve this problem!


This is my current version of a generic mathematical model:

using Microsoft.CSharp; using System;
using System.CodeDom.Compiler;
using System.Reflection;
namespace RuntimeCodeCompiling {
public static class Program
public static Action action;
public static void Main (string [] args)
Console.WriteLine ( "Sum (double):" + Generic_Math < double> .Sum (new double [] {1, 2, 3, 4, 5}));
Console.WriteLine ( "Sum (int):" + Generic_Math < int> .Sum (new int [] {1, 2, 3, 4, 5}));
Console.WriteLine ( "Sum (decimal):" + Generic_Math < decimal> .Sum (new decimal [] {1, 2, 3, 4, 5}));
Console.ReadLine ();
#region Generic Math Library Example
public static class Generic_Math < T>
public static Func < T [], T> Sum = (T [] array) =>
{// This implementation will make this string be stored in memory during runtime,
// So it might be better to read it from a file
string code = "(System.Func < NUMBER [], NUMBER>) ((NUMBER [] array) =>
{NUMBER sum = 0; for (int i = 0; i < array.Length; i ++) sum + = array [i]; return sum;}) ";
// This requires that "T" has an implicit converter from int values and a "+" operator
code = code.Replace ( "NUMBER", typeof (T) .ToString ());
// This small of an example requires no namspaces or references
Generic_Math < T> .Sum = Generate.Object < Func < T [], T >> (new string [] {}, new string [] {}, code);
return Generic_Math < T> .Sum (array);
/// < Summary> Generates objects at runtime. < / Summary>
internal static class Generate
/// < Summary> Generates a generic object at runtime. < / Summary>
/// < Typeparam name = "T"> The type of the generic object to create. < / Typeparam>
/// < Param name = "references"> The required assembly references. < / Param>
/// < Param name = "name_spaces"> The required namespaces. < / Param>
/// < Param name = "code"> The object to generate. < / Param>
/// < Returns> The generated object. < / Returns>
internal static T Object < T> (string [] references, string [] name_spaces, string code)
string full_code = string.Empty;
if (name_spaces! = null)
for (int i = 0; i < name_spaces.Length; i ++)
full_code + = "using" + name_spaces [i] + ";";
full_code + = "namespace Seven.Generated
{ ";
full_code + = "public class Generator
{ ";
full_code + = "public static object Generate ()
{Return "+ code +";}}} ";
CompilerParameters parameters = new CompilerParameters ();
foreach (string reference in references)
parameters.ReferencedAssemblies.Add (reference);
 parameters.GenerateInMemory = true;
CompilerResults results = new CSharpCodeProvider () CompileAssemblyFromSource (parameters, full_code).;
if (results.Errors.HasErrors)
string error = string.Empty;
foreach (CompilerError compiler_error in results.Errors)
error + = compiler_error.ErrorText.ToString () + "\ n";
throw new Exception (error);
MethodInfo generate = results.CompiledAssembly.GetType ( "Seven.Generated.Generator") GetMethod ( "Generate").;
return (T) generate.Invoke (null, null);

Code works:

If the general mathematical code is stored as a string, use the string hacking (aka macros aka string replace), to change the code at runtime. We can write a function and then change the type of the function when using this function. Therefore, we can assume that there must be a generic mathematical operators to implement this function.

The first time the function is called pan, it will build itself and re-assigned automatically. Thus, we do not have to deal with a stupid constructor, we only need to according to the desired functional structure.

As far as I know, you can not compile runtime compiler to use a single object, I just I need to compile a return value types. There may be an alternative, especially if you use a serialization technique of the time, but I am not very familiar with the deterioration degree format, so this method may be easier for me.

Each type requires only a version of the code.

There is no set method or constructor call method as we hoped it would self-configuration.

fast! This method is far as I know the only delegate calls cost overhead.

Small drawback :( these "shortcomings" can be overcome)
1. It can be annoying to write generic mathematical function as a string. Solution: I propose to write generic code in a separate file and parse. Such strings are not permanently stored in memory, you can still edit it, like in Visual Studio using C # as standard.

2. This is not an example of cross-platform. Patch: It is easy to achieve cross-platform functionality. According to their website said that as a reflection and runtime library that contains compiled Mono project. So long as the dynamic compiler can make search run "Generate" functional class cross-platform.

3. If the generic "typeof (T) .ToString ()" is embedded in the generics, the code will now collapse. Patch: Create a function and then create an appropriate string representation of this type and source code to achieve the same goal using some kind.

4. We still have compilation errors. Tell us custom type "struct Fraction128" forget overloaded "+" operator. It will also throw a runtime error. Patch: This problem can write a VS plug-in at compile time to detect the type of functional operation used contains the basic values and operators to be repaired. I just point out to these questions tell you that it is fixable, I will not do that. To use the time, do not do stupid things,: P

in conclusion

By using the run-time compiler, you can exist mathematical operators and value type conversion assumptions identified for the establishment of mandatory, so you can do some real meaning of math students. It is fast, as opposed to other methods described in this article is easy to maintain, and very powerful.
- C ++ containers (Programming)
- When a software RAID data recovery and reconstruction of how failure (Linux)
- Schema snapshot rollback (Database)
- Java 8 perspective annotation types (Programming)
- NAT (network address translation) Realization (Linux)
- HTML5 postMessage cross-domain data exchange (Programming)
- C language to view various types of data size (Programming)
- Linux see whether there is a hacker program (Linux)
- DNF Command Tutorial (Linux)
- SecureCRT remote connection Ubuntu fails to solve the case (Linux)
- Several back door and log tool under Linux (Linux)
- Linux system boot process ARM platforms (Linux)
- Linux package management (Linux)
- Java string concatenation techniques (StringBuilder tips) (Programming)
- MongoDB replication instance (Database)
- iOS in the event delivery and the responder chain (Programming)
- 12 Linux Process Management Commands (Linux)
- Ubuntu uses conky add desktop control (Linux)
- JITwatch installation under Linux (Linux)
- Python Socket Network Programming (Programming)
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.