Ищете надежную, общую реализацию op_Dynamic

Я не смог найти надежную, общую реализацию op_Dynamic: кто-нибудь может указать мне одну? До сих пор в поисках использовались только игрушки или конкретные реализации, но я бы хотел иметь такую ​​под рукой, которая, скажем, сравнивает по прочности со статической динамической реализацией C# по умолчанию (т. Е. Обрабатывает множество / все случаи, вызовы отражения кеша) (это Прошло много времени с тех пор, как я смотрел на статическую динамику в C#, так что извините, если мои утверждения о его возможностях неверны).

Спасибо!

2 ответа

Решение

В nuget есть модуль FSharp.Interop.Dynamic, который должен надежно обрабатывать динамический оператор с помощью dlr.

У этого есть несколько преимуществ перед многими фрагментами там.

  • Производительность он использует Dynamitey для вызова dlr, который реализует кэширование и является стандартной библиотекой.NET
  • Обрабатывая методы, которые возвращают void, вы получите обязательное исключение, если не откажетесь от результатов этих действий.
  • Dlr обрабатывает случай автоматического вызова возврата делегата функцией, это также позволит вам сделать то же самое с FSharpFunc
  • Добавляет!? Префиксный оператор для обработки вызова динамических объектов и функций, которые не имеют тип во время выполнения.

    Это открытый исходный код, лицензия Apache, вы можете посмотреть на реализацию, и она включает в себя примеры модульных тестов.

Вы никогда не сможете получить полностью общую реализацию ? оператор. Оператор может быть реализован по-разному для различных типов, где может потребоваться сделать что-то особенное в зависимости от типа:

  • За Dictionary<T, R>, вы хотите, чтобы он использовал функцию поиска в словаре
  • Для объектов SQL в моей статье, на которую вы ссылались, вы хотите, чтобы она использовала определенный API SQL
  • Для неизвестных объектов.NET вы хотите использовать.NET Reflection

Если вы ищете реализацию, которая использует Reflection, то вы можете использовать ту, которую я реализовал в привязке F# для MonoDevelop ( доступна на GitHub). Он достаточно полон и обрабатывает доступ к свойствам, вызовы методов, а также статические члены. (Остальная часть связанного файла использует его для вызова внутренних членов компилятора F#). Он использует Reflection напрямую, поэтому он довольно медленный, но довольно полнофункциональный.

Другой альтернативой может быть реализация оператора поверх.NET 4.0 Dynamic Language Runtime (чтобы он использовал тот же базовый API, что и dynamic в C# 4). Я не думаю, что есть реализация этого где-то там, но вот простой пример, как вы можете получить это:

#r "Microsoft.CSharp.dll"
open System
open System.Runtime.CompilerServices
open Microsoft.CSharp.RuntimeBinder

let (?) (inst:obj) name (arg:'T) : 'R =
  // Create site (representing dynamic operation for converting result to 'R 
  let convertSite = 
    CallSite<Func<CallSite, Object, 'R>>.Create //'
      (Binder.Convert(CSharpBinderFlags.None, typeof<'R>, null)) //'
  // Create site for the method call with single argument of type 'T
  let callSite = 
    CallSite<Func<CallSite, Object, 'T, Object>>.Create //'
      (Binder.InvokeMember
        ( CSharpBinderFlags.None, name, null, null, 
          [| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
             CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |]))
  // Run the method and perform conversion
  convertSite.Target.Invoke
    (convertSite, callSite.Target.Invoke(callSite, inst, arg))

let o = box (new Random())
let a : int = o?Next(10)

Это работает только для вызовов методов экземпляра с одним аргументом (Вы можете узнать, как это сделать, посмотрев код, сгенерированный компилятором C# для dynamic вызовы). I guess if you mixed the completeness (from the first one) with the approach to use DLR (in the second one), you'd get the most robust implementation you can get.

EDIT: I also posted the code to F# Snippets. Here is the version using DLR: http://fssnip.net/2U and here is the version from F# plugin (using.NET Reflection): http://fssnip.net/2V

Другие вопросы по тегам