1

In my code, I am trying to dynamically resolve which type parameter should be used for a generic method call.

    private int FooResolver<T1, T2>(bool condition, Func<int> fooMethod)
    {
        if (condition)
        {
            return fooMethod<T1>();
        }

        return fooMethod<T2>();
    }

I have created a wrapper method that takes in both type parameters and decides which one to use based on a condition... However, it seems C# does not allow this behavior. Are there any particular reasons for that? And is there a viable workaround for my code?

EDIT

After seeing the responses, I have decided to defer the type definition to the caller of the handler method:

private int FooResolver(bool condition, Func<int> foo1, Func<int> foo2)
{
    if (condition)
    {
        return foo1();
    }

    return foo2();
}

...

private int Bar()
{
    return FooResolver(myCondition, MyMethod<FirstType>, MyMethod<SecondType>);
}
Storm
  • 3,062
  • 4
  • 23
  • 54
  • 1
    You're `fooMethod` does not take any generic parameters, but you're trying to pass some to it. – Sean Jun 01 '20 at 08:59
  • 2
    1) You're passing in a `Func`. This takes an `int` and nothing else. 2) Your method returns an int. It can't return anything else. – canton7 Jun 01 '20 at 08:59
  • 3
    @canton7 `Func` doesn't take an `int` it returns one. – Johnathan Barclay Jun 01 '20 at 09:00
  • @Sean, please, can you explain how do I mark `fooMethod` to accept generic parameters? I couldn't find any answer to that... based on the C# semantics, it should be something like Foo fooMethod... but this is labeled as invalid syntax. – Storm Jun 01 '20 at 09:03
  • This is not possible. A workaround would be to pass a generic `MethodInfo`, and call `MakeGenericMethod`... which is not nice :-( – Sweeper Jun 01 '20 at 09:04
  • @MarcGravell Badly worded -- I meant its single generic type parameter is filled by `int` – canton7 Jun 01 '20 at 09:06
  • @canton7 But then point 2 doesn't stand, as the provided `Func` will return an `int`. – Johnathan Barclay Jun 01 '20 at 09:09
  • @JohnathanBarclay It's hard to tell what the intention is, but one interpretation is that OP wants to return different things based on `condition` (since they're calling a `Func` with different types of `T`, which means `fooMethod` returns different types, which they then try and return from `FooResolver`). My point 2 is that their `FooResolver` can only return `int`, not `T1` / `T2` – canton7 Jun 01 '20 at 09:14
  • 2
    @canton7 My interpretation is they are trying to pass int-returning generic methods, but agreed, the intention isn't clear. – Johnathan Barclay Jun 01 '20 at 09:16
  • @JohnathanBarclay, yes you are right, I was trying to pass int-returning generic method. – Storm Jun 01 '20 at 09:50

1 Answers1

2

Delegates aren't abstractions to open generic methods or method-groups; they are an indirection to a specific closed method - i.e. everything is already resolved. You can invoke it, and you can use reflection to find out what it is pointing at, but that's all (caveat: for simplicity I'm talking about delegates in the unicast sense; they are technically multicast, but that detail probably doesn't matter here).

If you want to get hold of a different method in the method-group (things that share the same name), or a different generic parameter usage of the same generic method: you'll need to use reflection to get hold of that. You can't do it directly from the delegate instance.

If you demonstrate the intended usage here, we may be able to offer more guidance on ways to achieve what you are after, but: it probably won't be as simple or direct as you are hoping.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900