2010-07-27 20 views
3

Quand je fais une requête qui retourne un type anonymeEst-ce que cette requête Linq peut être tapée autre chose que "var"?

var assets = 
     from Product p in Session.CreateLinq<Product>() 
     where bundles.Contains(p.ProductBundle) 
     select new {p.Asset, p.Asset.PropertyTbl}; 

Puis-je saisir le retour à autre chose que var?

+2

Pourquoi voulez-vous utiliser un autre type? Quel problème essayez-vous de résoudre? –

+0

'var' n'est pas un type! – AakashM

Répondre

6

Vous ne pouvez pas renvoyer un type anonyme car l'appelant ne saurait pas de quel type il s'agit et ne pourrait pas l'utiliser.

Si vous voulez retourner les résultats, vous pouvez créer des objets d'un type non anonyme:

IEnumerable<Foo> assets = 
    from Product p in Session.CreateLinq<Product>() 
    where bundles.Contains(p.ProductBundle) 
    select new Foo { Bar = p.Asset, Baz = p.Asset.PropertyTbl}; 

Vous pouvez également utiliser le type Tuple dans .NET 4 si vous ne voulez pas créer un classe personnalisée pour vos valeurs.


* Ceci n'est pas strictement vrai - c'est possible mais vous devriez éviter de le faire. Voici un link de toute façon si vous voulez vraiment.

+0

Merci pour la clarification. Je n'ai pas encore rencontré Tuple, je vais devoir vérifier. –

4

Vous pouvez utiliser object ou dynamic (dans .NET 4.0) au lieu de var mais ne vous attendez pas à trouver un nom à un type anonyme. Dans votre cas, l'utilisation de var est préférable car elle préserve la frappe forte au moins jusqu'à ce que vous quittiez la portée de la méthode actuelle.

+2

Mais dans ce cas, var est meilleur. – driis

+1

@driis, absolument –

+1

Notez qu'en utilisant 'object' au lieu de' var' il n'y aura pas d'intellisense pour les propriétés. –

0

Pas vraiment. Si vous lancez un objet, vous ne pourrez pas accéder aux propriétés de votre classe anonyme.

Le mot-clé var a été spécifiquement introduit pour traiter les classes anonymes - pourquoi voudriez-vous l'éviter? Si vous devez renvoyer les données, vous devez nommer la classe.

1

Vous pouvez définir une nouvelle classe:

public class AssetProp 
{ 
    public virtual string Asset {get;set;} 
    public virtual string PropertyTbl {get;set;} 
} 

Et vous pouvez le retourner comme cette classe:

IEnumerable<AssetProp> assets = 
    from Product p in Session.CreateLinq<Product>() 
    where bundles.Contains(p.ProductBundle) 
    select new AssetProp {p.Asset, p.Asset.PropertyTbl}; 
0

Pas vraiment, puisque le code new {p.Asset, p.Asset.PropertyTbl} crée un type anonyme. Même l'utilisation de object ne vous rapportera pas grand-chose puisque vous ne pourrez pas l'utiliser pour quelque chose d'utile plus tard, donc vous devrez utiliser la réflexion pour accéder aux propriétés.

0

Vous pouvez si vous utilisez lambda expressions, sinon vous pouvez faire une distribution, mais faire une bonne gestion des exceptions.

0

vous pouvez aussi le faire (il ne se rapporte beaucoup à votre problème cependant, parce que vous venez de déplacer « var » quelque part ailleurs, mais il est intéressant qu'il reconnaisse ces types comme même)

 var element = new { id = 7 }; 

     List<object> collection = new List<object>(); 
     element = collection.Select(item => new { id = 0 }).First();