2009-09-16 10 views
2

Je suis nouveau sur LINQ, j'ai essayé d'exécuter le code suivant et j'ai reçu l'erreur InvalidCastException: "Impossible de convertir l'objet de type 'd__3a`1 [debug.Product]' en type 'debug.Product' " - Qu'est-ce qui ne va pas?Impossible de lancer l'objet

code (VB - en utilisant VS2008)

Private Sub btnLinq_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLinq.Click 
     Dim Products As New List(Of Product) 

     Dim p1 As New Product 
     p1._ID = "1" 
     p1._Name = "Product A" 
     Products.Add(p1) 

     Dim p2 As New Product 
     p2._ID = "2" 
     p2._Name = "Product B" 
     Products.Add(p2) 

     Dim p3 As New Product 
     p3._ID = "3" 
     p3._Name = "Product C" 
     Products.Add(p3) 

     Dim prod As Product = From p In Products Where p._ID = "1" Select p Take 1 
     MsgBox(prod._ID) 

    End Sub 
End Class 

Public Class Product 
    Public _ID As String 
    Public _Name As String 
End Class 
+0

essayez avec temp comme var, et voir ce que le type de TEM est alors. – Natrium

Répondre

11

Prenez retourne un IEnumerable<Product> (dans votre cas), et non un produit. (Vérifiez par la sortie result.GetType()): (notez que mon exemple de code est en C#)

 List<Product> products = new List<Product>(); 

     products.Add (new Product() 
     { 
      Id = 1, 
      Name = "Prod1" 
     }); 

     products.Add (new Product() 
     { 
      Id = 2, 
      Name = "Prod2" 
     }); 


     var result = (from p in products 
         where p.Id == 1 
         select p).Take (1); 

     Console.WriteLine (result.GetType()); 

     Console.ReadLine(); 

Dans mon cas, le code ci-dessus sorties:

System.Linq.Enumerable+<TakeIterator>d__3a`1[LinqTest.Product] 

Dans votre cas , au lieu d'utiliser Take 1, vous pouvez essayer d'utiliser First ou FirstOrDefault à la place.

, essayez ceci:

 var result = (from p in products 
         where p.Id == 1 
         select p).FirstOrDefault(); 

     Console.WriteLine (result.GetType()); 
     Console.WriteLine (result.Name); 
+0

Merci ... vous avez été très utile. –

+0

Ensuite, vous devez marquer la réponse comme acceptée. :) –

+2

Dans le cas où vous ne voulez pas que le premier élément, vous pouvez utiliser '.Take (10) .ToList()' pour obtenir une liste générique au lieu de l'énumérable. – Designpattern

1

La méthode Take (Enumerable.Take) ne renvoie pas un élément plutôt elle renvoie une autre séquence (IEnumerable<Product>). Take(n) crée simplement une nouvelle séquence avec maximum de n éléments.

pour prendre le premier élément de la séquence en utilisant l'une des méthodes suivantes:

  • FirstOrDefault() - rendements null si la séquence est vide
  • First() - jets InvalidOperationException si la séquence est vide
Questions connexes