سؤال

I'm trying to implement a JsonRpc client class in C# which executes a given method / delegate / callback whenever the JsonRpc is responded (to explain why I need the thing I'm going to ask).

To this end I want a method to register a callback of arbitrary type (arbitrary argument list). This callback will be called / evaluated whenever the response arrives. This means that at registration time whatever the callback might be it is accepted and it's at execution time which its type might cause an exception, once it is checked with response's type.

I've seen codes implementing a similar concept like this:

//Defining a delegate based on a method signature
Delegate d = Delegate.CreateDelegate(delegate_type, context, methodInfo);

//Executing the delegate when response arrives
d.DynamicInvoke(parameters);

If I'm to implement the same, all I need to do is to accept an argument of type Delegate for registering a callback. But this won't do for me since I want it to be much easier to register a callback than creating its Delegate (it takes a dozen of lines to come up with a Delegate of a method).

At last here goes my question:

How would you implement registering a callback of arbitrary type in C#?

[UPDATE]

Or perhaps someone can come up with an easy way to create the Delegate of a method!?

هل كانت مفيدة؟

المحلول

I'm not sure what you mean when you say consumers will need to "create Delegates". Here's an example I came up with which works just fine and it doesn't seem that hard to do for consumers of your method.

private static void HigherOrderFoo(Delegate foo)
{
    var returnVal = foo.DynamicInvoke(null);
}

private static void Bar()
{
    HigherOrderFoo((Func<int>)(() => 10));
}

Likewise, the lambda function could just as well have been a method group and casting that to a delegate type would also have worked.

private static void HigherOrderFoo(Delegate foo)
{
    var returnVal = foo.DynamicInvoke(null);
}

private static void Bar()
{
    HigherOrderFoo((Func<int>)Baz);
}

private static int Baz()
{
    return 10;
}

Also, here's a great answer by Jon Skeet which explains why you need to cast the parameter to the actual delegate type in order to convert it to a Delegate.

Edit: If the method you're passing in as a parameter had it's own parameters, you could probably use the params keyword to pass in the parameters to HigherOrderFoo.

private static void HigherOrderFoo(Delegate foo, params object[] list)
{
    var bar = foo.DynamicInvoke(list);
}

private static void Bar()
{ 
    HigherOrderFoo((Func<int, int>)Baz, 10);
}

private static int Baz(int val)
{
    return val * val;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top