In F#, we can create a function like this:
let ``add x and y`` x y = x + y
And I can call it normally like this:
``add x and y`` 1 2
Is there a way to call the function above from C# side? I couldn't even see it in Object Browser though.
Definition. Idiom: call for (something) to demand or require something.
call for something to publicly ask for something to happen They called for the immediate release of the hostages. The opposition party has called for him to resign.
(call for someone/something) to go somewhere and get someone or something in order to take them to another place.
verb (tr, adverb) to cancel or abandonthe game was called off because of rain. to order (an animal or person) to desist or summon awaythe man called off his dog. to stop (something) or give the order to stop.
You can expose any valid F# function name to C# as any C# valid function name using CompiledName attribute:
namespace Library1
module Test =
[<CompiledName("Whatever")>]
let ``add a and b`` x y = x + y
and then in C#:
using Library1;
...............
System.Console.WriteLine(Test.Whatever(2,2));
FOLLOW-UP 03/05/2016 on comment from NickL, applies at least to F#3.1:
Moving from functions to members brings some "ifs and buts".
To begin with, CompiledName
attribute does not compile with member
if being used from pure namespace
. The mere compilation requires use within a module
.
When being used within a module
and decorating method member
of F# record it works just fine regardless of how the contents between two ticks looks. However when decorating property member
of F# record CompiledName
is visible cross-assembly only if contents between double ticks resembles some legal value name:
module M
type MyRecord =
{ myField: string }
[<CompiledName "Whatever">]
member x.``Blah Blah blah``() = x.myField
[<CompiledName "Another">]
member x.``ABC`` = x.myField
and then from C# the following works OK:
var recInC = new M.MyRecord("Testing...");
Console.WriteLine(recInC.Whatever());
Console.WriteLine(recInC.Another);
Such inconsistencies prompt for potential issues.
Reflection might be the only way, but it doesn't have to be ugly to use. Just wrap it all within a class to do the reflecting.
public static class MyModuleWrapper
{
// it would be easier to create a delegate once and reuse it
private static Lazy<Func<int, int, int>> addXAndY = new Lazy<Func<int, int, int>>(() =>
(Func<int, int, int>)Delegate.CreateDelegate(typeof(Func<int, int, int>), typeof(MyModule).GetMethod("add x and y"))
);
public static int AddXAndY(int x, int y)
{
return addXAndY.Value(x, y);
}
// pass other methods through.
public static int OtherMethod(int x, int y)
{
return MyModule.OtherMethod(x, y);
}
}
Then use it like normal.
var sum = MyModuleWrapper.AddXAndY(1, 2);
var otherValue = MyModuleWrapper.OtherMethod(1, 2); // use the wrapper instead
I'm not sure what needs to be changed or how if there are polymorphic types involved, but hopefully you get the idea and can apply the necessary changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With