Sherlock
Sherlock

Reputation: 5627

List of Func delegates with varying return types and number of parameters

I have a class that will require a varying number of Func delegates to be passed in the contructor. Each of these delegates will point to a different function, each with a different return type, and with a varying number of parameters (of type double). Each of these functions will then be called accordingly.

Question 1. Right now, to make things easier for those using this class, I am thinking about allowing the user to pass a List<object> of Func delegates. Is this possible, and if so am I able to determine the return type and number of params required for each Func in the method in which the List<object> is passed to (i.e. the constructor) ?

Question 2. If the above is not feasible, will I need to overload the constructor with every different combination of return types/number of params and route each Func accordingly -_- ... if not can someone point me in the right direction, I feel like i'm approaching this in the wrong way ...

note - coming from a python background, I would do something like this (i'm inexperienced in c#):

import inspect
def test(x): return x
inspect.getargspec(test)

returns: ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

Many thanks

Upvotes: 4

Views: 4286

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1503090

Question 1. Right now, to make things easier for those using this class, I am thinking about allowing the user to pass a List of Func delegates. Is this possible, and if so am I able to determine the return type and number of params required for each Func in the method in which the List is passed to (i.e. the constructor) ?

Not really. You could allow a List<Delegate> (or some other collection with an element type of Delegate), but nothing Func-specific, for two reasons:

  • Func is effectively a family of types, with different number of generic type parameters. These types are entirely separate as far as the CLR is concerned; Func<TResult> and Func<T, TResult> are as different as Action<T> and EventHandler.

  • Even if you were only dealing with several values of the same generic type of delegate, the fact that they could have different type arguments means they're different types to the CLR; there's no way of saying List<Func<>> for "a list of functions with potentially varying type arguments". Again, the CLR treats them as separate types - although this time at least one with a common generic type definition.

Question 2. If the above is not feasible, will I need to overload the constructor with every different combination of return types/number of params and route each Func accordingly

Well, there are several options:

  • Make all the parameters optional, giving each of them a default value of null, then use named arguments when calling the constructor:

     var foo = new Foo(clickHandler: () => ...,
                       keyHandler: key => ...);
    
  • Create a builder, so that the various functions can be set as properties - this works very well with the object initializer syntax:

     var foo = new Foo.Builder {
                   ClickHandler = () => ...,
                   KeyHandler = () => ...
               }.Build();
    

Both of the latter solutions depends on you really having a specific named purpose, of course.

It would help if you could be clearer about what you're trying to achieve - as dtb says, polymorphism may be a better fit here. You could create an abstract class with no-op implementations of virtual methods, and implementations could choose which ones to override.

Upvotes: 8

Related Questions