I've come across some strange behaviour in Visual Studio 2010 when using anonymous methods in functions that have overloads of various Func delegates.
I've created a small reproduction class below.
Consider this ListViewAdapter class
namespace LambdaTestApp
{
public class ListViewAdapter<T>
{
private Func<int, string, int, string> _converter1;
private Func<RefType1, string, string> _converter2;
public ListViewAdapter(int arg1, Func<int, string, int, string> converter)
{
_converter1 = converter;
}
public ListViewAdapter(int arg1, Func<RefType1, string, string> converter)
{
_converter2 = converter;
}
public static ListViewAdapter<T> MockPopulate(int arg, Func<int, string, int, string> converter) {
ListViewAdapter<T> instance = new ListViewAdapter<T>(arg, converter);
return instance;
}
public static ListViewAdapter<T> MockPopulate(int arg, Func<RefType1, string, string> converter)
{
ListViewAdapter<T> instance = new ListViewAdapter<T>(arg, converter);
return instance;
}
}
public class RefType1
{
public string Property1 { get; set; }
}
}
And this following code that uses the overload with a lambda:
namespace LambdaTestApp
{
class Program
{
static void Main(string[] args)
{
ListViewAdapter<RefType1>.MockPopulate(1, (item, str) =>
{
var myItem = item;
return str;
});
}
}
}
It should resolve to Func<RefType1, string, string>
and the first argument should be RefType1
, however the issue is that instead of item
being a RefType1
Visual Studio sees it as an int
.
Question: Is there a valid conversion between the Func delegates that isn't obvious, or is this a Visual Studio IntelliSense bug?
I would personally agree that it's a bug - or at least a flaw. Even though it only shows up when the code is invalid - and it's only when the code within the lambda expression is invalid - I think it would be more appropriate for Intellisense to view the parameter declaration part of the lambda expression (the part before =>
) as complete, and work based on that information.
There's nothing you can put within the body of the lambda expression which would change the overload resolution in a way which would make the choice of Func<int, string, int, string>
valid... there just aren't enough parameters.
I would at least suggest logging a Connect issue about this - it may well be "working as intended" in terms of "MS didn't design it to cope with this scenario" but it could clearly work better. Note that it's still working this way in the VS11 beta, although admittedly the laptop I'm running on at the moment hasn't applied the recent update to the beta. I wouldn't be surprised if you got a response which amounted to "Yes, that would be nice - but it would take a huge amount of work for little gain" but it's worth raising anyway, IMO.