Visual Studio错误解决方法中的lambda与Func委托重载?

时间:2012-03-30 18:33:21

标签: c# visual-studio lambda func overload-resolution

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

我在下面创建了一个小型复制课。

考虑这个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; }
    }
}

以下代码使用带有lambda的重载:

namespace LambdaTestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ListViewAdapter<RefType1>.MockPopulate(1, (item, str) =>
            {
                var myItem = item;
                return str;
            });
        }
    }
}

它应解析为Func<RefType1, string, string>,第一个参数应为RefType1,但问题是item而不是RefType1 Visual Studio将其视为{ {1}}。

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

3 个答案:

答案 0 :(得分:5)

我个人认为这是一个错误 - 或者至少是缺陷。即使它仅在代码无效时出现 - 并且仅当lambda表达式中的代码无效时 - 我认为Intellisense更适合查看lambda的参数声明部分表达式(=>之前的部分)完成,并根据该信息工作。

在lambda表达式的 body 中没有任何内容可以改变重载决策,这样可以使Func<int, string, int, string>的选择有效...只是没有'足够的参数。

至少建议记录一个Connect问题 - 这可能是“按预期工作”的“MS没有设计它来应对这种情况“但它显然可以更好地运作。请注意,它仍然在VS11测试版中以这种方式工作,尽管我现在正在运行的笔记本电脑尚未应用最新更新测试版。如果你的反应达到了“是的,这将会很好 - 但这需要大量工作才能获得收益”,我不会感到惊讶,但无论如何它都值得提升,IMO。

答案 1 :(得分:2)

  

它应解析为Func<RefType1, string, string>,第一个参数应为RefType1,但问题是,RefType1 Visual Studio不是将项目视为int

只要存在编译错误,通过查看第一个重载函数,

Visual Studio 就会猜到int。它无法确定使用哪个重载,因为它无法理解代码。它可能能够更好地猜测你可能意味着哪一个,但认为这是一个错误有点苛刻。

修复错误后,Visual Studio可以告诉参数类型为RefType1。您可以通过确保代码编译,然后将鼠标悬停在item上来验证这一点。

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

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

答案 2 :(得分:0)

LINQ的方法重载解析完全与C#一样:基于参数的数量和类型,仅此而已。论证是否通用是无关紧要的。

如果没有看到PopulateListView中的代码,我就不得不说你传递了一个int,这就是你得到的。