C# Visual Studio使用Func委托重载解决方法中的lambda错误?

C# Visual Studio使用Func委托重载解决方法中的lambda错误?,c#,visual-studio,lambda,func,overload-resolution,C#,Visual Studio,Lambda,Func,Overload Resolution,我在VisualStudio2010中遇到了一些奇怪的行为,在函数中使用匿名方法时,函数重载了各种Func委托 我在下面创建了一个小的复制类 考虑这个ListViewAdapter类 namespace LambdaTestApp { public class ListViewAdapter<T> { private Func<int, string, int, string> _converter1; private Fu

我在VisualStudio2010中遇到了一些奇怪的行为,在函数中使用匿名方法时,函数重载了各种Func委托

我在下面创建了一个小的复制类

考虑这个ListViewAdapter类

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; }
    }
}
名称空间LambdaTestApp
{
公共类ListViewAdapter
{
专用函数转换器1;
专用功能转换器2;
公共ListViewAdapter(int arg1,Func转换器)
{
_转换器1=转换器;
}
公共ListViewAdapter(int arg1,Func转换器)
{
_converter2=转换器;
}
公共静态ListViewAdapter(int-arg,Func-converter){
ListViewAdapter实例=新的ListViewAdapter(参数,转换器);
返回实例;
}
公共静态ListViewAdapter(int-arg,Func-converter)
{
ListViewAdapter实例=新的ListViewAdapter(参数,转换器);
返回实例;
}
}
公共类RefType1
{
公共字符串属性1{get;set;}
}
}
下面的代码使用lambda重载:

namespace LambdaTestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ListViewAdapter<RefType1>.MockPopulate(1, (item, str) =>
            {
                var myItem = item;
                return str;
            });
        }
    }
}
名称空间LambdaTestApp
{
班级计划
{
静态void Main(字符串[]参数)
{
ListViewAdapter.MockPopulate(1,(项,str)=>
{
var myItem=项目;
返回str;
});
}
}
}
它应该解析为
Func
,第一个参数应该是
RefType1
,但是问题是,Visual Studio将
视为
RefType1
而不是
int


问题:Func委托之间是否存在不明显的有效转换,或者这是Visual Studio IntelliSense错误?

LINQ的方法重载解析与C#完全相同:基于参数的数量和类型,仅此而已。参数是否是泛型的无关紧要

如果没有在
PopulateListView
中看到代码,我不得不说您正在传递一个int,这就是您得到的结果

它应该解析为
Func
,第一个参数应该是
RefType1
,但是问题是,VisualStudio将它视为
int
,而不是
RefType1

只要存在编译错误,VisualStudio就会通过查看第一个重载函数来猜测它是
int
。它无法确定使用了哪个重载,因为它无法理解代码。它也许能在猜测你可能指的是哪一个方面做得更好,但是考虑这个bug有点苛刻。 修复错误时,Visual Studio可以判断参数类型为
RefType1
。您可以通过确保代码已编译,然后将鼠标悬停在
项上来验证这一点

是的,不幸的是,这意味着因为键入
至少会暂时使代码无效,并将显示
int
的成员。如果确实需要,可以调用
item.ToString(),然后用新的
覆盖
。然后,您将看到您希望看到的列表


或者,确保首先列出最常用的重载,以使Visual Studio做出不同的猜测。

我个人同意这是一个bug,或者至少是一个缺陷。即使它只在代码无效时才显示——并且只在lambda表达式中的代码无效时显示——我认为Intellisense更适合将lambda表达式的参数声明部分(前面的部分)视为完整,并基于该信息进行工作

在lambda表达式的主体中没有任何内容可以改变重载分辨率,从而使选择
Func
有效。。。只是没有足够的参数


我至少建议记录一个关于这个问题的日志——它很可能“按预期工作”,即“MS没有设计它来处理这个场景”,但它显然可以工作得更好。请注意,它在VS11测试版中仍然以这种方式工作,尽管我目前运行的笔记本电脑没有将最新的更新应用到测试版。如果您得到一个相当于“是的,那太好了——但这需要大量的工作才能获得很少的收益”的响应,我不会感到惊讶,但无论如何,我认为这是值得提出的。请查找lambda中的其他错误。对,代码是否编译?首先让它编译,然后从那里向后工作,以了解发生了什么。对于泛型和重载,这种方法通常更容易。旁注:当您有10个以上的方法参数时,您可能会缺少一些其他参数。这些参数应该重构为某种类型的
Args
class@GETah,您在哪里看到这些“10”方法参数?(我数了5,这是一个非常合理的数字)@GETah,别傻了。查看
System.Linq.Enumerable
中大约一半的方法。最好单独评估给定方法的正确设计,而不是试图提出“代码气味”它试图鼓励您采用一种设计,而不必费心仔细考虑。
Func
比它的参数多了一个泛型类型参数:返回类型也是泛型类型参数。@hvd:你知道,我知道,而且应该比编写它更清楚。我整天都在Func工作。谢谢你的更正。我已编辑以删除无意义的愚蠢。@MikeHofer我已用不同的代码更新/修订了该问题。@dmck虽然它不是针对我的,谢谢,我起初不知怎么搞不懂这个问题,但我理解了