1

I want to pass a Func<IList<object>, int> to a method that takes a Func<IEnumerable<object>, int>. Can't seem to work it out. Is it possible to do something like below?

    class A {
        void Test() {
            IList<object> data = new List<object>();

            // can't pass in MyFunc, doesn't compile
            ApplyFunc(MyFunc, data);
        }

        int MyFunc(IList<object> data) {
            return 0;
        }

        void ApplyFunc(Func<IEnumerable<object>, int> f, IList<object> data) {
            f(data);
        }
    }
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
CoderBrien
  • 663
  • 1
  • 7
  • 22
  • 2
    This is possibly a duplicate of https://stackoverflow.com/questions/36006997/func-variance-with-multiple-parameters/36007182 or https://stackoverflow.com/questions/13025176/conversion-from-funcobject-string-to-funcstring-string-works-but-to-funcint. – kiziu Sep 15 '16 at 22:43

3 Answers3

3

Because the delegate in question is defined as Func(in T, ...), you only allowed to use a less derived type. IList(T) implements IEnumerable(T) which is more derived.

(From kiziu's comment...) Conversion from Func<object,string> to Func<string,string> works but to Func<int,string> fails

Possible solutions are to use a lambda (as described in one of the other answers) or change the signature of MyFunc

Scott Perham
  • 2,410
  • 1
  • 10
  • 20
2

Your Test method can be as follows:

public void Test()
{
    IList<object> data = new List<object>();

    ApplyFunc(x => MyFunc(x as IList<object>), data);
}
L.B
  • 114,136
  • 19
  • 178
  • 224
-2

If generics are an option, you can do:

class A {
    void Test() {
        IList<object> data = new List<object>();

        // can't pass in MyFunc, doesn't compile
        ApplyFunc(MyFunc, data);
    }

    int MyFunc(IList<object> data) {
        return 0;
    }

    void ApplyFunc<TEnumerable>(Func<TEnumerable, int> f, TEnumerable data)
         where TEnumerable : IEnumerable<object>
    {
       f(data);
    }
}

See the fiddle: https://dotnetfiddle.net/juEWYf

Nico
  • 3,542
  • 24
  • 29