Note that there are some explanatory texts on larger screens.

plurals
  1. POIs there a way to simplify this reflective delegate code in C#?
    primarykey
    data
    text
    <p>In <a href="https://stackoverflow.com/a/12867132/171121">this</a> response, I came up with the following helper method that could be reused by different <code>Task</code> creators to convert events into task completion sources.</p> <pre><code>// Helper method static Task&lt;T&gt; TaskFromEventHelper&lt;T&gt;(object target, string eventName, Func&lt;TaskCompletionSource&lt;T&gt;, object&gt; resultSetterFactory) { var tcs = new TaskCompletionSource&lt;T&gt;(); var addMethod = target.GetType().GetEvent(eventName).GetAddMethod(); var delegateType = addMethod.GetParameters()[0].ParameterType; var d = Delegate.CreateDelegate(delegateType, resultSetterFactory(tcs), "Invoke"); addMethod.Invoke(target, new object[] {d}); return tcs.Task; } // Empty events (Action style) static Task TaskFromEvent(object target, string eventName) { return TaskFromEventHelper(target, eventName, (Func&lt;TaskCompletionSource&lt;object&gt;, object&gt;)(tcs =&gt; (Action)(() =&gt; tcs.SetResult(null)))); } // One-value events (Action&lt;T&gt; style) static Task&lt;T&gt; TaskFromEvent&lt;T&gt;(object target, string eventName) { return TaskFromEventHelper(target, eventName, (Func&lt;TaskCompletionSource&lt;T&gt;, object&gt;)(tcs =&gt; (Action&lt;T&gt;)(tcs.SetResult))); } // Two-value events (Action&lt;T1, T2&gt; or EventHandler style) static Task&lt;Tuple&lt;T1, T2&gt;&gt; TaskFromEvent&lt;T1, T2&gt;(object target, string eventName) { return TaskFromEventHelper(target, eventName, (Func&lt;TaskCompletionSource&lt;Tuple&lt;T1, T2&gt;&gt;, object&gt;)(tcs =&gt; (Action&lt;T1, T2&gt;)((t1, t2) =&gt; tcs.SetResult(Tuple.Create(t1, t2))))); } </code></pre> <p>In each of the three examples I gave that use the helper method, there's a <code>tcs.SetResult</code> component, which makes me think there's a way to move that to the helper method too, which might perhaps simplify the signatures, so that perhaps the helper method would just have to accept a <code>Func&lt;?, T&gt;</code>, where that <code>Func</code> would take the output of the <code>event</code> and convert it to whatever <code>tcs.SetResult</code> takes. </p> <p>i.e., I'm thinking there must be a way to create a helper so I can write it as</p> <pre><code>// Empty events (Action style) static Task TaskFromEvent(object target, string eventName) { return TaskFromEventHelper&lt;object&gt;(target, eventName, new Func&lt;object&gt;(() =&gt; null)); } // One-value events (Action&lt;T&gt; style) static Task&lt;T&gt; TaskFromEvent&lt;T&gt;(object target, string eventName) { return TaskFromEventHelper&lt;T&gt;(target, eventName, new Func&lt;T, T&gt;(t =&gt; t)); } // Two-value events (Action&lt;T1, T2&gt; or EventHandler style) static Task&lt;Tuple&lt;T1, T2&gt;&gt; TaskFromEvent&lt;T1, T2&gt;(object target, string eventName) { return TaskFromEventHelper&lt;Tuple&lt;T1, T2&gt;&gt;(target, eventName, new Func&lt;T1, T2, Tuple&lt;T1, T2&gt;&gt;(Tuple.Create)); } </code></pre> <p>, but that's why I don't know the <code>?</code> in <code>Func&lt;?, T&gt;</code> above. This one for example needs <code>?</code> to be <em>two</em> parameters. Could it be passed in as <code>object</code> somehow? I have a feeling it could be possible, but if so it needs some real reflection magic.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload