Reputation: 18746
I've just written a simple method that C# can see but calling it (even with valid arguments) throws up at run-time.
example that fails at runtime:
F#:
namespace Library1
type Class1() =
member __.Foo = "F#"
module MyModule =
// fails at run-time
let inline fOnly (x:^a) : string = (^a:(member Foo: _) x)
// works from C# and F# so I know it's not a problem with my stp
let testFOnly () = fOnly (Class1())
C# consumer:
namespace ConsoleApplication1
{
class Program
{
var class1 = new Library1.Class1();
// NotSupportedException
var result = Library1.MyModule.fOnly(class1);
Console.ReadLine();
}
}
Why does this compile, then fail at run-time? Am I doing something wrong or should I just assume any attempt to call an stp method from C# will always fail? Should I then attempt to hide them from C#?
Upvotes: 0
Views: 71
Reputation: 370
The code in the example is wrong
Class1
has the member Foo
not X
and it fails to compile
-------------- After Question Edit ------------
You can use ILSpy to see the decompiled code and the source of the error
Decompiled C# -
namespace Library1
{
[CompilationMapping(SourceConstructFlags.Module)]
public static class MyModule
{
public static string fOnly<a>(a x)
{
"Dynamic invocation of get_Foo is not supported";
throw new NotSupportedException();
}
public static string testFOnly()
{
Class1 @class = new Class1();
return "F#";
}
}
}
But you can see from the code that this will work
static void Main ( string [ ] args )
{
Console.WriteLine( Library1.MyModule.testFOnly()) ;
Console.ReadLine();
}
There's also no reason to make this a function call
let testFOnly () = fOnly (Class1())
instead of a regular binding since it's targeting an immutable property of the class.
i.e. let testFOnly = Class1() |> fOnly
Upvotes: 2
Reputation: 25516
The use of inline
in F# doesn't actually produce a function in the output assembly.
The function is encoded in some metadata that only the F# compiler can read and then insert inline.
As a result, you cannot call inline
functions from C#
Upvotes: 2