Question

So I guess I don't really understand the above. Like suppose you have an extension on an enumerable type like so....

public static TElement StringMatch<TElement, TData>(
        this IEnumerable<TElement> source,
        Func<TElement, TData> selector)

All is fine here, but I've been assuming that the StringMatch generic parameters mirror the Func generic parameters, since the Func<> is what appears to the user to be passed.

But say I want to specify that the return type of Func<> is a specific parameter, maybe like Func<TElement, string>

Now my thought would be to alter the signature like so...

public static TElement StringMatch<TElement, string>(
            this IEnumerable<TElement> source,
            Func<TElement, string> selector)

...again, to mirror the passed Func<>. But if I try to invoke this on something like Books.StringMatch(b => b.Title), I get an error like...

'Book' does not contain a definition for 'StringMatch' and no extension method 'StringMatch' accepting a first argument of type 'Book' could be found (are you missing a using directive or an assembly reference?) 

So what's the deal here? What exactly do the generic parameters in an extension method specify?

Was it helpful?

Solution

Once you have

public static TElement StringMatch<TElement, TData>(
    this IEnumerable<TElement> source,
    Func<TElement, TData> selector)

it covers the case where the caller passes a Func where TData is string.

If you want TData to always be the specific type string then simply remove that as a formal generic parameter in the method:

public static TElement StringMatch<TElement>(
    this IEnumerable<TElement> source,
    Func<TElement, string> selector)

You can, of course, implement both. The compiler will select the most specific one. The caller can also specify the type parameters explicitly to leave only one choice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top