繁体   English   中英

Visual Studio 2015 Intellisense无法确定某些泛型方法中lambda的类型

[英]Visual Studio 2015 Intellisense fails to determine types of lambdas in some generic methods

注意:这是Roslyn中的一个错误,已在Visual Studio 2017中修复。

Visual Studio 2015无法确定Enumerable.Join等方法中的lambda参数类型。 请考虑以下代码:

public class Book
{
    public int AuthorId { get; set; }
    public string Title { get; set; }
}

public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public static void NoIntellisenseInEnumerableJoin()
{
    IEnumerable<Book> books = null;
    IEnumerable<Author> authors = null;

    //Intellisense fails on both 'book => book.AuthorId' and 'author => author.Id'
    var test = books.Join(authors, book => book.AuthorId, author => author.Id, (book, author) => new { book, author });
}

当我输入book => book. 没有出现。 当我将鼠标悬停在book ,Intellisense标记它(parameter) ? book (parameter) ? book

我试图解决它

  • devenv.exe /resetuserdata
  • 删除.suo,.vs等,虽然每个项目都会发生在我团队中的每个人身上
  • 完成了这个c-sharpcorner列表中的所有九个步骤除了一对似乎不适用于Visual Studio 2015的一对。
  • 发了一个“皱眉头”

附加信息

  • 问题与Func<>Expression<Func<>>同样发生
  • Intellisense似乎工作正常(除了荒谬的JavaScript处理时间,这是另一个故事...)
  • 这个问题只发生在2015年。这个例子在2010年,2012年和2013年都运行良好,尽管我的一个队友最近在2013年围绕更新4开始遇到一个非常类似的问题。
  • 我使用的是Visual Studio Enterprise 2015版本14.0.24620.00 Update 1,但在安装Update 1之前出现了同样的问题。
  • 在所有类似的情况下都不会出现这个问题。 例如, books.Select(book => book.正常工作。
  • 如果我在写完声明后回来,VS知道它是一Book并给了我正确的选项。 这导致了一个有趣的解决方法,我可以在其中输入books.Join(authors, , , ) ,然后填写空白并再次获得智能感知。
  • 它似乎与泛型类型的推断有关。 请参阅下面的自酿示例。 Wrapper<Book>.Combine(authors, book => book.AuthorId, author => author.Id适用于book但不适用于authorbook的类型来自类的泛型参数,但author的类型来自方法的。
  • 令人惊讶的是,明确指定类型并不总能解决问题。
  • 起初我认为问题是Join有多个覆盖,但问题发生在下面的本土示例中没有覆盖。

一个本土的例子

public class Wrapper<TInner>
{
    public void Combine<TOuter, TKey>(Wrapper<TOuter> outer, Func<TInner, TKey> innerKey, Func<TOuter, TKey> outerKey)
    { }

    public void ThisWorks<TOuter>(Wrapper<TOuter> outer, Func<TInner, int> innerKey, Func<TOuter, int> outerKey)
    { }
}

public static class WrapperExtensions
{
    public static void CombineExt<TInner, TOuter, TKey>(this Wrapper<TInner> inner, Wrapper<TOuter> outer,
        Func<TInner, TKey> innerKey, Func<TOuter, TKey> outerKey)
    { }

    public static void ThisAlmostWorks<TInner, TOuter>(this Wrapper<TInner> inner, Wrapper<TOuter> outer,
        Func<TInner, int> innerKey, Func<TOuter, int> outerKey)
    { }
}

public static class NoIntellisenseExamples
{
    public static void NoIntellisenseInSimplerCase()
    {
        var books = new Wrapper<Book>();
        var authors = new Wrapper<Author>();

        //Intellisense fails on 'author => author.Id' but works for the book lambda.
        books.Combine(authors, book => book.AuthorId, author => author.Id);

        new Wrapper<Book>().Combine<Author, int>(authors, book => book.AuthorId, author => author.Id);

        //Intellisense fails on both 'book => book.AuthorId' and 'author => author.Id' in both of the following:
        books.CombineExt(authors, book => book.AuthorId, author => author.Id);
        WrapperExtensions.CombineExt(books, authors, book => book.AuthorId, author => author.Id);

        //Intellisense works perfectly here.
        books.ThisWorks(authors, book => book.AuthorId, author => author.Id);

        //Intellisense fails on 'book => book.AuthorId' but works for 'author => author.Id'
        books.ThisAlmostWorks(authors, book => book.AuthorId, author => author.Id);
    }
}

我试过输入你的第一个例子,同样的事情发生在我身上。 我输入book => book. 一无所获:

在此输入图像描述

完整的声明

为什么会这样,我不知道。 我只能假设它的东西做的陈述不完整,因为一旦该语句完整的,我可以回去删除.AuthorId ,然后我得到了智能感知book变量:

在此输入图像描述

解决方法

这不是一个很好的解决方案,但您可以通过在lambda语句中声明变量的类型来解决此问题。 当你这样做时,你应该得到intellisense:

在此输入图像描述

以下是当您尝试编写代码并依赖于泛型类型的智能感知解释时,智能感知可能发生的情况的解释,以及确定在编写book => book.时要提供的类选项book => book. 或者author => author.

1。

public void Combine<TOuter, TKey>(Wrapper<TOuter> outer, Func<TInner, TKey> innerKey, Func<TOuter, TKey> outerKey) {}

//Intellisense fails on 'author => author.Id' but works for the book lambda.
books.Combine(authors, book => book.AuthorId, author => author.Id);

这里,作为参数传递给查询的TKey是book类型,与TOuter匹配。 所以作者会失败。

2。

public void ThisWorks<TOuter>(Wrapper<TOuter> outer, Func<TInner, int> innerKey, Func<TOuter, int> outerKey){}

//Intellisense works perfectly here.
books.ThisWorks(authors, book => book.AuthorId, author => author.Id);

这是有道理的,因为有一种类型作为参数传递给查询书籍,然后其中的每个函数都使用它的参数类型传递,并且它是相应的密钥。

3。

public static void CombineExt<TInner, TOuter, TKey>(this Wrapper<TInner> inner, Wrapper<TOuter> outer,
    Func<TInner, TKey> innerKey, Func<TOuter, TKey> outerKey) {}

//Intellisense fails on both 'book => book.AuthorId' and 'author => author.Id' in both of the following:
books.CombineExt(authors, book => book.AuthorId, author => author.Id);
WrapperExtensions.CombineExt(books, authors, book => book.AuthorId, author => author.Id);

在这里我不确定,但不清楚TKey被分配给什么类型,书籍或作者。

4。

public static void ThisAlmostWorks<TInner, TOuter>(this Wrapper<TInner> inner, Wrapper<TOuter> outer,
    Func<TInner, int> innerKey, Func<TOuter, int> outerKey) { }

//Intellisense fails on 'book => book.AuthorId' but works for 'author => author.Id'
books.ThisAlmostWorks(authors, book => book.AuthorId, author => author.Id);

在这里,我怀疑你用this Wrapper覆盖了Type,所以它正在使用作者。

对于你的var测试:

IEnumerable<Book> books = null;  
IEnumerable<Author> authors = null;

您从列表中选择为空,因此它们都会失败。 尝试初始化它们,就像在进一步的代码中一样。

对于现实生活代码:

然后将AuthorId更改为Author。 您需要能够从两个表中进行选择。 就个人而言,我发现这是一种更简单的方法来处理绑定,使用模型视图和在数据库上运行查询。

public class Book
{
    public Author Author { get; set; }
    public string Title { get; set; }
}

public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public static void NoIntellisenseInEnumerableJoin()
{
    IEnumerable<Book> books = null;
    IEnumerable<Author> authors = null;


var books_  = from book in books
                       select book;

var books = books.Include(book => book.Author);

books_ = books_.Where(book => book.Author.Id, // to do.

对于创建新对象,我不会通过像这样的链接查询来执行此操作。 作者要么存在,要么需要创建,可以创建书籍,既可以添加Author Author ,也可以使用int AuthorId

Book类还需要一个ID作为功能数据库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM