为什么StaticallyResolvedTypeParameter方法在运行时失败时会调用compile?

时间:2016-02-02 21:13:30

标签: c# .net f# inline static-typing

我刚刚编写了一个简单的方法,C#可以看到但是调用它(即使使用有效的参数)也会在运行时抛出。

在运行时失败的示例:

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#消费者:

namespace ConsoleApplication1
  {
    class Program
    {
      var class1 = new Library1.Class1();
      // NotSupportedException
      var result = Library1.MyModule.fOnly(class1);
      Console.ReadLine();    
    }
  }

为什么要编译,然后在运行时失败?我做错了什么或者我是否应该假设从C#调用stp方法的任何尝试都会失败?我应该attempt to hide them from C#吗?

2 个答案:

答案 0 :(得分:2)

在F#中使用inline实际上并没有在输出程序集中生成函数。

该函数在一些元数据中编码,只有F#编译器才能读取然后插入内联。

因此,您无法从C#

调用inline函数

答案 1 :(得分:2)

示例中的代码错误

Class1成员Foo不是X且无法编译

--------------问题编辑后------------

您可以使用ILSpy查看反编译代码和错误来源

反编译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#";
        }
    }
}

但是您可以从代码中看到这将起作用

static void Main ( string [ ] args )
{
  Console.WriteLine( Library1.MyModule.testFOnly()) ;
  Console.ReadLine();  
}

也没有理由将其作为函数调用 let testFOnly () = fOnly (Class1()) 而不是常规绑定,因为它的目标是类的不可变属性。

即。 let testFOnly = Class1() |> fOnly