Discussion: Permit static lambda assignment to function pointers · dotnet/csharplang · Discussion #6746 (original) (raw)
Considering this spec
Removing the static modifier from a lambda in a valid program does not change the meaning of the program.`
I would find it useful to be able to directly assign a lambda to a function pointer without & or static, as long as no variables are captured.
My use case is, I have a library that supports old versions of Unity (C# 4), and I conditionally compile with newer C# language features for better performance.
A simplified example similar to what I'm doing:
internal delegate void ConvertDelegate(object asyncResult, ref T storage, int index);
internal Merger : IAsyncResult, IIndexedCallback { internal T _result; private ConvertDelegate _converter;
internal Merger(ConvertDelegate<T> converter)
{
_converter = converter;
}
void IIndexedCallback.Callback(object asyncResult, int index)
{
_result = _converter(asyncResult, ref _result, index);
}
T IAsyncResult<T>.Result { get { return _result; } }}
public static AsyncResult<ValueTuple<T1, T2>> Merge<T1, T2>(AsyncResult result1, AsyncResult result2) { var merger = new Merger<ValueTuple<T1, T2>>((object asyncResult, ref ValueTuple<T1, T2> storage, int index) => { if (index == 0) { storage.Item1 = ((IAsyncResult) asyncResult).Result; } else { storage.Item2 = ((IAsyncResult) asyncResult).Result; } }); result1.AddIndexedListener(merger, 0); result2.AddIndexedListener(merger, 1); return new AsyncResult<ValueTuple<T1, T2>>(merger); }
...
public static AsyncResult<ValueTuple<T1, T2, T3, T4>> Merge<T1, T2, T3, T4>(AsyncResult result1, AsyncResult result2, AsyncResult result3, AsyncResult result4) { ... }
And it would be very convenient for me if I could just change the Merger implementation to this so that the lambda expressions wouldn't have to change to fit function pointers and reduce duplicate code:
#if CSHARP_12_OR_GREATER // Or whichever language version private delegate*<object, ref T, int, void> _converter;
internal Merger(delegate*<object, ref T, int, void> converter)
{
_converter = converter;
}#else private ConvertDelegate _converter;
internal Merger(ConvertDelegate<T> converter)
{
_converter = converter;
}#endif
I know my use case is super niche and this may be unlikely to happen, but I figured I should give my input here.