Say I have a basic function, like:
let double x = x * 2
Since I know the types, I can convert it into a Func<_,_> explicitly, which can then be used as a Delegate:
let doubleFuncExplicit = Func<int, int>(double)
However, when I attempt to do this by using Activator.CreateInstance() instead of the constructor, like so:
// derive the type for Func<int, int>
let genericType = typeof<Func<obj, obj>>.GetGenericTypeDefinition()
let specificTypeDef = genericType.MakeGenericType([| typeof<int>; typeof<int> |])
// ...and instantiate it
let doubleFuncReflected = Activator.CreateInstance(specificTypeDef, [| double |])
…I get the following exception on the last line:
System.MissingMethodException: Constructor on type 'System.Func`2[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]' not found.
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
at System.Activator.CreateInstance(Type type, Object[] args)
at <StartupCode$FSI_0007>.$FSI_0007.main@() in C:\dev\2023\MoneyClock2023\src\MoneyClock\MoneyClock.Tests\Scratch.fsx:line 16
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Am I on the right track? How can I convert an F# function into a delegate?
>Solution :
Yes, you are on the right track, but the reason you’re getting a MissingMethodException is because the Func<,> type is a generic type, and its constructor takes a delegate as an argument, not a function. To convert an F# function into a delegate, you can use the System.Func<,>.CreateDelegate method, like this:
let doubleFuncDelegate = System.Func<_,_>.CreateDelegate(typeof<int -> int>, double)
This will create a delegate of type Func<int, int> that you can use in your code.