2016-02-02 2 views
0

Я только что написал простой метод, который C# может видеть, но вызов его (даже с допустимыми аргументами) подбрасывается во время выполнения.Почему метод StaticResolvedTypeParameter вызывает компиляцию при сбое во время выполнения?

пример, который терпит неудачу во время выполнения:

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();  
    } 
    } 

Почему это компиляции, затем не во время выполнения? Я что-то делаю неправильно или должен ли я предположить, что любая попытка вызвать метод stp из C# всегда будет терпеть неудачу? Должен ли я тогда attempt to hide them from C#?

ответ

2

Использование inline в F # фактически не производит функцию в выходном сборке.

Функция кодируется в некоторых метаданных, которые может читать только компилятор F #, а затем вставлять встроенные.

В результате, вы не можете вызвать inline функции из C#

+1

C#, чтобы назвать это компилирует. Кроме того, следующие компиляции и работы 'let inline add x y = x + y' вызывается из C# как' var inlinedAdd = Library1.MyModule.add (1,2); 'так что вы можете вызывать' inline' функции из C#? – Maslow

+1

@Maslow - это меня удивляет - возможно, компилятор создает резервную версию без встроенной версии, где это возможно? –

+0

что меня удивляет, это то, что люди поддержали ответ, который потребовал простой функции добавления, чтобы опровергнуть. – Maslow

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()) вместо обычного связывания, поскольку он нацелен на неизменяемое свойство cla песчаники

т.е. let testFOnly = Class1() |> fOnly

+0

мой плохой, отрегулировал только половину F #, чтобы сделать его немного более читаемым для вопроса SO, обновленный вопрос – Maslow

+0

Я действительно удивлен, что он не встраивает вызов члену как встроенный, а вместо этого берет значение времени компиляции, возможно, это сделало бы что-то более интересное/интуитивное, если бы оно было указано на функцию вместо prop/field с постоянным значением – Maslow

Смежные вопросы