2011-12-16 6 views
0

LINQとVBを学習していて、匿名型のフィールドにアクセスしようと1時間を費やしました。 linqクエリ。キー(私が学んだこと)は、の前に、クエリをリストに変換することです。これは、forループを使って反復しようとします。 How to access property of anonymous type in C#?linqクエリの最後に.toListを追加すると、匿名型のプロパティにのみアクセスできます。

これは動作しません:編集(これはコンパイルが、インテリセンスが型を認識しない)

Dim varbl=from itm in collct select New With {.n=itm.Name} 'query here 
for each returnedItem in varbl 
    returnedItem.n 'intellisense does not pick up the property names 
next 

をしかし、これは行います

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

誰かがなぜ/どのように説明できますやっている?上の(そうでなければ役立つ!)ポストは、「コンパイラが動作する方法のために、匿名型が同じ構造を持ち、同じ型であるため、リストを作成した後でも動作するはずです。私はこれを検証するために手渡すコンパイラを持っていません。 "

+0

これはあなたの質問に答えることはできませんが、ちょうど始めているのであれば、VBの代わりにC#を学ぶことを強くお勧めします。あなたに役立つ多くのサンプルコードと記事があります。 – danludwig

+0

私は@olivehourを知らないのですが、いつも私が知りたいことのどこかでWeb上でチュートリアルを書いている人を除いて、すべての世界コードがC#であるようです。 –

答えて

2

私のVBは非常に錆びていて、かなり古くなっています(約10年前のVB6です)。しかし、.NETの観点からは何かが間違っているように見えました。

あなたがリンクしている回答(あなたのIMOの説明では不完全)は間違っています。匿名のオブジェクトをリストに入れる必要はありませんが、それはList<object>に入れられていました。つまり、コンパイラがどのプロパティを持っているのかわかりませんでした(objectのオブジェクトではありません)。問題の匿名型であり、objectにはCheckedというプロパティはありません)。

とにかく。私はいくつかのC#にあなたの最初の試みを書いてみました:持っていた

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); 
} 

その後、私はコンパイルされ、反射鏡に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を使用してVBではなくC#を使用していますが(IDEであれば使用しています)あなたは実際に正しいコードを持っていましたが、IntelliSenseはそれを認識しませんでした。

IntelliSenseはかなりコンパイルされていますが、コンパイラではありません。タイプするうちに私たちの速度を低下させる危険があるため、コンパイラとして多くのリソースを費やすことはできません。

ちなみに、ではありません。実際には目的のリストが必要でない限り、ToListに電話してください。 collctが、データベースまたはファイルから何かを読み込む際に何千ものオブジェクトを返す列挙型としてロードされているとします。

ToListに電話をかけると、最初のデータが到着するとすぐに反復処理が開始され、一度に一度に少数のメモリを使用するだけで済みます。

ToListを呼び出すと、メモリ内の大量のリストにすべてのオブジェクトがロードされるまで、プログラムはその行に止まり、For Eachを開始します。

もちろん、リストを前後に移動したり、繰り返しを行う前にカウントを知る必要がある場合は、For Eachを繰り返すよりもToListを呼び出す方がいいでしょう。しかし、あなたがを知っていない場合は、それを使用する必要がありますを知っている。

+0

こんにちは。ご回答有難うございます。私は.toListを削除し、コードをコンパイルして正常に実行しました。私はあなたが正しいと思う:これは、intellisenseがコンパイラほどスマートではなかった場合です。ちょうどb/c intelsenseは型を認識しませんでしたが、コンパイラが型を認識しないことを意味しませんでした。どうやら(おそらくあなたが知っているように)C#では、Varキーワードはコードがコンパイルされるまで型が割り当てられていない変数を保持しています。私の推測では、VBのDimは同じように動作します。おそらくtoListを追加して、「事前に割り当てられた」型をどうにかしていますか?とにかく、noobの鍵はintellsenseがコンパイラではないということです – bernie2436

+0

Hehは、 "経験豊富な"ユーザーよりも優れていることを学ぶ "noob"です。そして、実際に経験豊富なユーザー(1年の経験ではなく何年もの経験を何年も経験している)でさえ、IntelliSenseが突然何かを拾わないときは、それは気にしません。 –

+0

しかし、コンパイラ型の変数(C#の 'var'、' As'のない 'Dim'、' Option Infer On')は通常、IntelliSenseによって選ばれます。それはちょうどそれがうまくいかない、または不完全に働くことです。 –

関連する問題