InSharp 1.0.2

.NET Standard 2.0
dotnet add package InSharp --version 1.0.2
NuGet\Install-Package InSharp -Version 1.0.2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="InSharp" Version="1.0.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add InSharp --version 1.0.2
#r "nuget: InSharp, 1.0.2"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install InSharp as a Cake Addin
#addin nuget:?package=InSharp&version=1.0.2

// Install InSharp as a Cake Tool
#tool nuget:?package=InSharp&version=1.0.2

InSharp

Library for runtime MSIL functions compilation

How to use

  1. Create ILGen object ILGen<[Method delegate type]> gen = new ILGen<[Method delegate type]>([Mathod name], [enable private fields and classes access]);

  2. Write code with statements

    • gen.Line for statements
      • Use class Expr to use operators (Example: Expr.Mul(gen.args[0], gen.Const(3.5f)), Expr.Greater(gen.args[0], 0))
      • To set value use Set method (Example: gen.Line(i.Set(0));) !Set is the statement and must be in gen.Line
    • gen.Return to return value
    • gen.If / gen.ElseIf / gen.Else / gen.EndIf for if construction
    • gen.While / gen.EndWhile for while cycles
  3. Call gen.compile([enable debug info]); to compile your function

Simple shell get/set/call/construct functions

Maybe you need only to compile function-caller / constructor / setter / getter for unknown type? You can use ILTemplate for these tasks:

Memebr getters
  • ILTemplate.CommonMemberGetter - for static and instance class members get. Returns Func<object, object>, where the first argument - object instance (if instance member) and the return value - field value
  • ILTemplate.StaticMemberGetter - for stastic class members get. As CommonMember getter, but the return function doesn't receive the object instance argument
  • ILTemplate.InstanceMemberGetter - for instance class members get. The first argument of the return function - object instance, return value - field value
Member setters
  • CommonMemberSetter - for static and instance class members set. Returns Action<object, object> where first argument - object instance (for instance fields) and the second - set value
  • StaticMemberSetter - for static members set. Result Action< object > is without object instance arg
  • InstanceMemberSetter for instance members set. Returns Action<object, object> where first argument - object instance and second - set value
Class constructor
  • Use CommonObjectCreator to compile function Func<object[], object>, that calls constructor with args in array of object and returns a new object instance
Method call shell
  • CommonCallShell - call shell for static and instance class methods, with and without return type. Returns Func<object, object[], object> , where the first argument - class instance (if calls instance function), the second - call function args array. Returns null, if call method has no return type
  • CommonStaticCallShell - call shell for static class methods with and without return type. Returns Func<object[], object>, where the first argument - call function args array.
  • StaticActionCallShell - call shell for static class methods without return type. Returns Action<object[]>, where the first argument - call function args array.
  • StaticFunctionCallShell - call shell for static class methods without return type. Returns Func<object[], object>, where the first argument - call function args array.
  • CommonInstanceCallShell - call shell for instance class methods with and without return type. Returns Func<object, object[], object> where the first arg - object instance, the second - function call args array. Returns null, if the call method has no return type
  • InstanceActionCallShell - call shell for instance class methods without return type. Returns Action<object, object[]> where the first arg - object instance, the second - function call args array.
  • InstanceFunctionCallShell - call shell for instance class methods with return type. Returns Func<object, object[], object> where the first arg - object instance, the second - function call args array.

Example 1

Function returns (first arg) * 3.5

ILGen<Func<int, float>> gen = new ILGen<Func<int, float>>("Example1_func", true);

//Function
gen.Return( Expr.Mul(gen.args[0], gen.Const(3.5f)) ) ;

var func = gen.compile(true); //Our function

Console.WriteLine("Result: {0}", func(15));

Example 2

If/elseif/else constructions

var gen = new ILGen<Action<int>>("TestFunc5_1", true);

//Function
gen.If(Expr.Greater(gen.args[0], 0));
//If arg0 > 0
gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", "{0} is positive", Expr.CreateArray(typeof(object), gen.args[0])));
gen.ElseIf(Expr.Less(gen.args[0], 0));
//Else if arg0 < 0
gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", "{0} is negative", Expr.CreateArray(typeof(object), gen.args[0])));
gen.Else();
//else (arg0 == 0)
gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", "Zero"));
gen.EndIf();


var func = gen.compile(true);

Example 3

Fibonacci numbers array gen

var gen = new ILGen<Func<int, long[]>>("TestFunc6", true);

//Function
ILVar resultArray = gen.DeclareVar(typeof(long[]));
ILVar arrayIndex = gen.DeclareVar(typeof(int));
gen.Line(resultArray.Set(Expr.InitArray(typeof(long), gen.args[0])));
gen.Line(resultArray.Index(0).Set(0));
gen.Line(resultArray.Index(1).Set(1));
gen.Line(arrayIndex.Set(2));
gen.While(Expr.NotEquals(arrayIndex, resultArray.ArrayLength));
	gen.Line(resultArray.Index(arrayIndex).Set(resultArray.Index(arrayIndex - 1) + resultArray.Index(arrayIndex - 2)));
	gen.Line(arrayIndex.Set(arrayIndex + 1));
gen.EndWhile();
gen.Return(resultArray);

var func = gen.compile(true);

Example 4

Double fields of unknown type sum function

var gen = new ILGen<Func<T, double>>(typeof(T).Name + "_fields_sum", true);

ILVar counter = gen.DeclareVar<double>();
gen.Line(counter.Set(0.0));
foreach(FieldInfo fieldInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(info => info.FieldType == typeof(double)))
	gen.Line(counter.Set(counter + gen.args[0].Field(fieldInfo)));
gen.Return(counter);

var func = gen.compile(true);

Example 5

Create a matrix and output it to console

var gen = new ILGen<Action>("TestFunc14", true);

ILVar matrix = gen.DeclareVar(typeof(int[,]));
gen.Line(matrix.Set(Expr.CreateArray(typeof(int), new Expr[] { 
		1, 2, 3,
		4, 5, 6,
		7, 8, 9
	}, new int[] { 3, 3})));

ILVar index1 = gen.DeclareVar(typeof(int));
gen.Line( index1.Set(0) );
ILVar index2 = gen.DeclareVar(typeof(int));
gen.Line( index2.Set(0) );
ILVar lineString = gen.DeclareVar(typeof(string));

gen.While( Expr.Less(index1, matrix.GetArrayDimensionLength(0)) );
	gen.Line( lineString.Set("") );
	gen.Line( index2.Set(0) );
	gen.While( Expr.Less(index2, matrix.GetArrayDimensionLength(1)) );
		gen.Line( lineString.Set(Expr.Add(Expr.Add(lineString, matrix.Index(index1, index2).CompatiblePass(typeof(string))), "; ")) );
		gen.Line( index2.Set(Expr.Add(index2, 1)) );
	gen.EndWhile();
	
	gen.Line(Expr.CallStatic(typeof(Console), "WriteLine", lineString));

	gen.Line( index1.Set(Expr.Add(index1, 1)) );
gen.EndWhile();

var func =  gen.compile(true);

Example 6

Create delegate instance and call it

delegate int TestDelegate(int a, int b);

public static int testAddition(int a, int b) {
	Console.WriteLine($"Call testAddition with args a = {a}, b = {b}");
	return a + b;
}

public static void testFunc17() { 
	var gen = new ILGen<Func<int, int, int>>("TestFunc17", true);
	ILVar delegateVar = gen.DeclareVar(typeof(TestDelegate));

	gen.Line(delegateVar.Set(Expr.CreateDelegate(typeof(TestDelegate), Expr.NULL, typeof(Program).GetMethod("testAddition", BindingFlags.Public | BindingFlags.Static))));
	gen.Return(delegateVar.Invoke(gen.args[0], gen.args[1]));

	var func = gen.compile(true);
	int result = func(5, 6);
	Console.WriteLine($"Result: {result}");
}

More examples

IL compile
IL create by templates

Also

To see MSIL code, I used ILSpy. Codes to view MSIL are in ShowCode

Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on InSharp:

Package Downloads
SerializeMethodsAutoBuilder

C# library for auto build serialize and deserialize to byte array methods for given type (based on NetBinSerializer).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.2 364 5/16/2021
1.0.1 192 5/16/2021
1.0.0 191 5/13/2021