How to make inline functions in C#
Yes, C# supports that. There are several syntaxes available.
Anonymous methods were added in C# 2.0:
Func<int, int, int> add = delegate(int x, int y)
{
return x + y;
};
Action<int> print = delegate(int x)
{
Console.WriteLine(x);
}
Action<int> helloWorld = delegate // parameters can be elided if ignored
{
Console.WriteLine("Hello world!");
}Lambdas are new in C# 3.0 and come in two flavours.
Expression lambdas:
Func<int, int, int> add = (int x, int y) => x + y; // or...
Func<int, int, int> add = (x, y) => x + y; // types are inferred by the compilerStatement lambdas:
Action<int> print = (int x) => { Console.WriteLine(x); };
Action<int> print = x => { Console.WriteLine(x); }; // inferred types
Func<int, int, int> add = (x, y) => { return x + y; };
Local functions have been introduced with C# 7.0:
int add(int x, int y) => x + y;
void print(int x) { Console.WriteLine(x); }
There are basically two different types for these: Func
and Action
. Func
s return values but Action
s don't. The last type parameter of a Func
is the return type; all the others are the parameter types.
There are similar types with different names, but the syntax for declaring them inline is the same. An example of this is Comparison<T>
, which is roughly equivalent to Func<T, T, int>
.
Func<string, string, int> compare1 = (l,r) => 1;
Comparison<string> compare2 = (l, r) => 1;
Comparison<string> compare3 = compare1; // this one only works from C# 4.0 onwards
These can be invoked directly as if they were regular methods:
int x = add(23, 17); // x == 40
print(x); // outputs 40
helloWorld(x); // helloWorld has one int parameter declared: Action<int>
// even though it does not make any use of it.
Inline functions in C#?
Finally in .NET 4.5, the CLR allows one to hint/suggest1 method inlining using MethodImplOptions.AggressiveInlining
value. It is also available in the Mono's trunk (committed today).
// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices;
...
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)
1. Previously "force" was used here. I'll try to clarify the term. As in the comments and the documentation, The method should be inlined if possible.
Especially considering Mono (which is open), there are some mono-specific technical limitations considering inlining or more general one (like virtual functions). Overall, yes, this is a hint to compiler, but I guess that is what was asked for.
Creating Inline Functions and Macros
Inline functions in C#?
Finally in .NET 4.5, the CLR allows one to force1 method inlining
using MethodImplOptions.AggressiveInlining value. It is also available
in the Mono's trunk (committed today).
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
void Func()
{
Console.WriteLine("Hello Inline");
}
How to force inline functions in C#?
Sort of. It's not under your direct control to turn on for sure. It's never inlined in the IL - it's only done by the JIT.
You can explicitly force a method to not be inlined using MethodImplAttribute
[MethodImpl(MethodImplOptions.NoInlining)]
public void Foo() { ... }
You can also sort of "request" inlining as of .NET 4.5:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Foo() { ... }
... but you can't force it. (Prior to .NET 4.5, that enum value didn't exist. See the .NET 4 documentation, for example.)
Inline functions in C#?
Finally in .NET 4.5, the CLR allows one to hint/suggest1 method inlining using MethodImplOptions.AggressiveInlining
value. It is also available in the Mono's trunk (committed today).
// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices;
...
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)
1. Previously "force" was used here. I'll try to clarify the term. As in the comments and the documentation, The method should be inlined if possible.
Especially considering Mono (which is open), there are some mono-specific technical limitations considering inlining or more general one (like virtual functions). Overall, yes, this is a hint to compiler, but I guess that is what was asked for.
Inline function blocks in C#
The way C# does this is with lambdas:
void mysequence() {
transform.DOMoveX(4, 1).OnComplete(() => {
// do more stuff here
});
}
From the documentation you linked to:
// Callback without parameters
transform.DOMoveX(4, 1).OnComplete(myCallback);
// Callback with parameters
transform.DOMoveX(4, 1).OnComplete(()=>myCallback(someParam, someOtherParam));
Passing object to an inline function in C#
You already have the solution:
f(nameof(Temperature), Temperature);
Because that information can't be inferred from this:
f(Temperature);
There'd be no way for the internals of f
to know what variable name was used, or if one was used at all. What if you did this?:
f("123.45");
f(temperatures[0]);
f(someObj.GetTemperature());
f(await this.Temperatures.SingleOrDefaultAsync(t => t == "123.45"));
What would the "variable names" be?
That information isn't provided to the method, so you'll need to provide it manually if you need it. Basically, variables aren't passed to the method, values are.
Wrapping INLINE functions
inline: Tagging a method inline is an instruction to the compiler to not emit a function call, but to instead take the contents of the method, and put it directly into the calling function. I believe this is only advisory, the compiler can choose to emit a function call anyway. Regardless, you don't need to do anything fancy when calling this function from C++/CLI, so you don't need to do anything fancy when wrapping it. Just wrap it the same as any other method.
private variables: If they're private variables, then unmanaged C++ code using PABCon
wouldn't have access to them. The public interface of PABCon
is just the public methods, so that's all you need to worry about. (If the C++ class had any public variables, then you'd wrap them by creating a property in C++/CLI.)
~PABConWrapper
: In C++/CLI, ~
is not the destructor, it's the dispose method. As implemented right now, you'll have a memory leak if you forget to dispose your new class. At a minimum, switch the ~
to !
, and declare the finalizer instead. Ideally, implement both !
and ~
, delete the unmanaged object in both methods (with a proper null check), and add proper null checks in the other methods. This would be a good & proper implementation of IDisposable.
Inline function definition
You can do like this
Func<int,bool> HasFullAccess = mask => mask % 2 == 1;
Related Topics
How Is Math.Pow() Implemented in .Net Framework
Making a Simple Ajax Call to Controller in ASP.NET MVC
Make Https Call Using Httpclient
How to Elevate Privileges Only When Required
Entity Framework Join 3 Tables
Getting Value from Appsettings.JSON in .Net Core
Is Double Multiplication Broken in .Net
How to Protect My .Net Assemblies from Decompilation
Mono Shared Library Under Linux Location
How to Create a Simple Proxy in C#
Why Do Assignment Statements Return a Value
Conversion of a Datetime2 Data Type to a Datetime Data Type Results Out-Of-Range Value
Difference Between Console.Read() and Console.Readline()
Differencebetween Debug and Release in Visual Studio
What's the Difference Between Task.Start/Wait and Async/Await