Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 为什么在将.toList添加到linq查询的末尾时只能访问匿名类型的属性_Vb.net_Linq_Anonymous Types - Fatal编程技术网

Vb.net 为什么在将.toList添加到linq查询的末尾时只能访问匿名类型的属性

Vb.net 为什么在将.toList添加到linq查询的末尾时只能访问匿名类型的属性,vb.net,linq,anonymous-types,Vb.net,Linq,Anonymous Types,我正在学习LINQ和VB,只花了一个小时试图访问LINQ查询中定义的匿名类型的字段。我学到的关键是在尝试使用for循环迭代查询之前,将查询转换为列表。 此操作不起作用:编辑(此操作可编译,但intellisense无法识别该类型) 但这确实: Dim varbl=(from itm in collct select New With {.n=itm.Name}).toList for each returnedItem in varbl returnedItem.n 'this w

我正在学习LINQ和VB,只花了一个小时试图访问LINQ查询中定义的匿名类型的字段。我学到的关键是在尝试使用for循环迭代查询之前,将查询转换为列表。

此操作不起作用:编辑(此操作可编译,但intellisense无法识别该类型)

但这确实:

Dim varbl=(from itm in collct select New With {.n=itm.Name}).toList
for each returnedItem in varbl 
     returnedItem.n 'this works
next 

有人能解释一下发生了什么事吗?上面的帖子(其他方面也很有用!)只是说“因为编译器的工作方式,一旦创建了列表,下面的内容也应该可以工作,因为匿名类型具有相同的结构,所以它们也是相同的类型。我手头没有编译器来验证这一点”

好吧,我不打算回答,因为我的VB已经非常生锈,而且已经过时了(呃,大约十年前的VB6)。但是,从.NET的角度来看,这里确实出现了一些问题

你对你链接到的答案的阅读(IMO的解释不完整)是错误的。这并不是说你需要把匿名对象放到一个列表中,而是那里的查询已经把它放到了一个
列表中,这意味着编译器无法分辨它有什么属性(它处理的是
对象
不是所讨论的匿名类型的对象,并且
对象
没有选中的
属性)

不管怎样,我试着把你最初的尝试写进一些C#as:

然后我在reflector中编译并反编译为VB.NET,它将我的
Main
作为:

Public Shared Sub Main()
    Dim collct As TestType() = New TestType() { New TestType("abc"), New TestType("def"), New TestType("xyz") }
    Dim varbl = (From itm In collct Select New With { _
        .n = itm.Name _
    })
    Dim returnedItem
    For Each returnedItem In varbl
        Console.WriteLine(returnedItem.n)
    Next
End Sub
看起来很像你的原作,不是吗

好吧,它工作了;它编译并运行,给了我正确的答案

我能想到的唯一一件事是,IntelliSense可能在这里不太合适。我发现,在过去的一些时候,IntelliSense很难建议匿名类型的属性名称,而我使用SharpDevelop来编写C#而不是VB(在您使用的任何IDE中),这里可能就是这种情况-您实际上一直都有正确的代码,但IntelliSense没有意识到这一点

归根结底,IntelliSense非常好,但它不是编译器,而且它不能像编译器那样花费太多的资源来做事情,因为在我们打字时,它可能会减慢我们的速度

顺便说一句,除非您确实需要一个列表,否则您不应该调用
ToList
。想象一下,如果
collct
是一个按需加载的枚举,从数据库或文件加载内容后,它将返回数千个对象

如果您不调用
ToList
,那么在第一个数据到达后,您将立即开始遍历它们,并且一次只需要使用少量内存

若您确实调用了
ToList
,那个么程序将停留在该行,直到它将每个对象加载到内存中的一个大列表中,然后才为每个
启动


当然,有时您确实需要能够在列表中前后移动,或者在迭代之前知道计数,然后调用
ToList
当然比不断重复每个
要好,但是如果您不知道您需要它,就不要使用它。

这并不能回答您的问题,但如果您需要的话刚开始,我强烈建议你学习C#,而不是VB。你会找到更多的示例代码和文章来帮助你。我不知道@olivehour似乎世界上所有的代码都是C#,除了在网上某个地方写教程的家伙,关于我想知道的事情:)嗨,Jon。谢谢你的回答。我删除了.toList,代码编译后运行良好。我认为你是对的:在这种情况下,intellisense没有编译器那么聪明。只是b/c intelsense不能识别类型,并不意味着编译器也不能识别类型。显然(您可能知道)在C#中,Var关键字包含一个变量,在编译代码之前,该变量的类型不会被赋值。我猜VB的Dim也是这样工作的。也许会添加toList“预先指定”的类型?无论如何,对于noob来说,关键是intellsense不是编译器,一个比一些“有经验”的用户做得更好的“noob”。即使是真正有经验的用户(多年的经验,而不是一年的几次经验)也会发现IntelliSense突然没有发现什么东西时令人不安。不过,编译器键入了变量(
var
in C#,
Dim
不带
As
和带
选项推断on
)通常由IntelliSense接收。它只是偶尔不起作用,或者不完全起作用。
private class TestType
{
  public string Name{get;set;}
  public TestType(string name)
  {
    this.Name = name;
  }
}
public static void Main()
{
  TestType[] collct = new TestType[]{new TestType("abc"), new TestType("def"), new TestType("xyz")};
  var varbl = from itm in collct select new {n = itm.Name};
  foreach(var returnedItem in varbl)
    Console.WriteLine(returnedItem.n);
}
Public Shared Sub Main()
    Dim collct As TestType() = New TestType() { New TestType("abc"), New TestType("def"), New TestType("xyz") }
    Dim varbl = (From itm In collct Select New With { _
        .n = itm.Name _
    })
    Dim returnedItem
    For Each returnedItem In varbl
        Console.WriteLine(returnedItem.n)
    Next
End Sub