2

A colleague wrote this extension method that I wanted to produce an example for:

namespace ExtensionMethods {
    public static class MyExtensions {
        public static Res MyAggregate<T, Res>(this IEnumerable<T> source, Func<Res, int, T, Res> f) {
            var i = 0;
            Res result = default(Res);
            foreach (T x in source) {
                result = f(result, i, x);
                i++;
            }
            return result;
        }
    }
}

It creates a generic Aggregate method that also includes an index.

My example (that follows) takes a list of strings and joins the 1st letter from the first word, the 2nd from the second, etc..

namespace ExtensionMethods {

    public class Program {
        public static string OffsetChars(string x, int i, string y) {
            return x + y[i];
        }

        static void Main(string[] args) {
            List<string> test = new List<string>() { "hello", "there", "you" };
            // get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
            string result = test.MyAggregate<string, string>(OffsetChars);
            Console.WriteLine(result);

            Console.ReadKey();
        }
    }
}

My question is about this line (the important one):

string result = test.MyAggregate<string, string>(OffsetChars);

Without <string, string> there is an error that the types of arguments cannot be inferred from usage. My question(s):

Why cannot they be inferred? Is there something missing from my code that would enable them to be inferred?

I tested with an explicit delegate (follows) but the same error occurs:

namespace ExtensionMethods {
    delegate string OffsetMethod(string x, int i, string y);

    public class Program {
        public static string OffsetChars(string x, int i, string y) {
            return x + y[i];
        }

        static void Main(string[] args) {
            List<string> test = new List<string>() { "hello", "there", "you" };
            // get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)

            OffsetMethod myMethod = OffsetChars;

            string result = test.MyAggregate(myMethod);
            Console.WriteLine(result);

            Console.ReadKey();
        }
    }
}

To summarize, I want to ensure that I haven't missed anything with my code and, assuming that I haven't, to understand why the parameter types cannot be inferred.

Andy G
  • 19,232
  • 5
  • 47
  • 69

2 Answers2

1

Your method is just a delegate and therefore does not have any generic type arguments that could be infered. When you define OffsetChars as a generic Func, they can be infered just fine:

public static Func<string, int, string, string> OffsetChars = (x, i, y) =>
{
    return x + y[i];
};
wertzui
  • 5,148
  • 3
  • 31
  • 51
-1

WERTZUI is right, because the delegate does not have any generic arguments, compiler cannot infer it, so you have se error.