4

在具有各种 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,但问题是它不是itemVisual RefType1Studio 而是将其视为int.

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

4

3 回答 3

5

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

在 lambda 表达式的主体中没有任何内容可以改变重载决议,从而使选择Func<int, string, int, string>有效……只是没有足够的参数。

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

于 2012-04-14T08:32:21.210 回答
2

它应该解析为Func<RefType1, string, string>并且第一个参数应该是RefType1,但是问题是,而不是 item 是RefType1Visual Studio 将其视为int.

只要存在编译错误,Visual Studio就会通过查看第一个重载函数来猜测它。int它无法确定使用了哪个重载,因为它无法理解代码。在猜测您可能指的是哪个方面可能会做得更好,但是将其视为错误有点苛刻。

修复错误后,Visual Studio 可以判断参数类型是RefType1. 您可以通过确保代码编译,然后将鼠标悬停在item.

是的,不幸的是,这意味着由于键入.至少会暂时使代码无效,并且会显示int. 如果你真的需要,你可以item.ToString();以一种满足编译器的方式调用,然后.用新的.. 然后,您将看到您希望的列表。

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

于 2012-04-12T19:12:14.670 回答
0

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

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

于 2012-03-30T18:39:59.603 回答