2010-06-28 18 views
1

Le code est faux:Pour Linq Select Statement, comment construire une sous-classe de manière générale au moment de l'exécution?

public class ParentClass 
     { decimal quantity, 
     decimal price 
     } 

    IQueryable<ParentClass> parents; 

    //SonClass is created at run time 
    //SonClass has some extra property, such as amount=quantity*price, which is defined by a string at run time 

    IQueryable<SonClass> sons=parents.Select(p=>new SonClass(p){ attachedProperty1=..., attachedProperty2=...}) 

Si je le code source de ParentClass, je sais comment créer le sonClass au moment de l'exécution. En fait, SonClass devrait avoir un constructeur approprié pour l'instruction Linq select. J'ai essayé le code suivant faux:

public SonClass(ParentClass parent) 
{ 
... 
} 

Quand on n'a pas le code source de ParentClass, comment écrire un code générique?

Ou, peut-être que vous avez une nouvelle façon d'obtenir le même résultat. Les résultats souhaités consistent à créer dynamiquement une sous-classe de ParentClass avec des propriétés supplémentaires en lecture seule définies par l'instruction Linq Select.

Merci d'avance.

Ying

+0

Un exemple de type défini par l'utilisateur peut être utilisé dans l'instruction LINQ Select.http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/01/25/using-your-own-defined-type-in-a-linq-query-expression.aspx. – Ying

+0

s'il s'agit d'une classe dynamique (donc les propriétés ne sont pas connues avant l'exécution), que va faire le consommateur? vous pouvez utiliser IDynamicObject je suppose - http://stackoverflow.com/questions/245975/how-do-you-implement-c4s-idynamicobject-interface –

+0

1. Bien que ce soit une classe dynamique, c'est une sous-classe de la classe d'origine . Donc, le consommateur le traitera comme l'original. 2. Il semble que IDynamicObject n'est pas ce que je cherche. Merci. – Ying

Répondre

0

vous ne devez pas construire une sous-classe, une classe anonyme est généré pour vous lors de l'exécution

var sons=parents.Select(p=>new { attachedProperty1=p..., attachedProperty2=p...}) 
foreach (var son in sons){ 
    Console.WriteLine(son.PropertyName); 
} 
1

Je ne crois pas que ce soit (actuellement) possible. Guide du programmeurs C# à MSDN, en ce qui concerne anonymous types:

types anonymes sont les types de référence qui dérivent directement de l'objet. Le compilateur leur donne un nom bien que votre application ne peut pas y accéder. Du point de vue de l'exécution de la langue commune , un type anonyme est pas différent de tout autre type de référence , sauf qu'il ne peut pas être converti en n'importe quel type sauf pour objet.

0

Il semble que vous souhaitiez créer un type dynamique qui étend un type existant et injecte des propriétés personnalisées. Je suis à peu près sûr que c'est impossible dans une seule déclaration LINQ (vous auriez besoin d'une dynamique C# 4.0 ou d'une folie de réflexion).

Cependant, vous pouvez créer des classes anonymes avec des propriétés vous:

var sons = parents.Select(p =>new { parentProperty1=p.Prop1, attachedProperty1=..., tachedProperty2=...}); 

Ou:

var sons = parents.Select(p =>new { parent=p, attachedProperty1=..., tachedProperty2=...}); 

Sinon, pourquoi avez-vous pas un "propriétés supplémentaires" (objet de type ou Dictionary) propriété sur votre ParentClass afin que vous puissiez le faire:

var sons = parents.ForEach(p => p.AdditionalProps = new { attachedProperty1=..., tachedProperty2=...}); 

Vous peut écrire une méthode d'extension qui a utilisé la réflexion pour récupérer toutes les propriétés publiques d'un objet donné, les fusionner avec un objet anonyme donné (votre objet "attachedProperty1 etc.") et retourner un nouvel objet anonyme avec toutes les propriétés fusionnées. Cependant, ce serait une mauvaise solution - une meilleure solution serait probablement de renvoyer une chaîne Dictionary, un objet au lieu d'un type anonyme car même si vous avez créé un type anonyme fusionné, vous ne pourrez pas accéder à ses propriétés dans une manière sûre de type.