Comment passer des types anonymes comme paramètres?
Comment puis-je transmettre les types anonymes comme des paramètres à d'autres fonctions? Considérons cet exemple:
var query = from employee in employees select new { Name = employee.Name, Id = employee.Id };
LogEmployees(query);
variable query
ici n'est pas de type fort. Comment dois-je définir mon LogEmployees fonction de l'accepter?
public void LogEmployees (? list)
{
foreach (? item in list)
{
}
}
En d'autres termes, que dois-je utiliser à la place de ?
marques.
Mieux différente double question qui traite avec passage de paramètres plutôt que de retourner des données: stackoverflow.com/questions/16823658/...
OriginalL'auteur Saeed Neamati | 2011-07-08
Vous devez vous connecter pour publier un commentaire.
Je pense que tu devrais faire une classe pour ce type anonyme. Ce serait la chose la plus sensée à faire à mon avis. Mais si vraiment vous ne voulez pas, vous pouvez utiliser la dynamique:
Noter que c'est pas fortement typé, donc, si, par exemple, les changements de Nom de EmployeeName, vous ne savez pas il y a un problème jusqu'à ce que l'exécution.
dynamic
d'utilisation. J'ai vraiment venu pratique pour moi. Merci 🙂Je suis d'accord qu'une fois que des données commence à être passé autour, de façon plus structurée peut / doit normalement être privilégiées afin de ne pas introduire dur de trouver des bugs (vous êtes contourner le système de type). Cependant, si vous souhaitez trouver un compromis, une autre façon est de simplement passer un Dictionnaire générique. C# dictionnaire des initialiseurs sont assez pratique à utiliser ces jours-ci.
Il y a certains cas où vous voulez un générique de mise en œuvre, et en passant dur de types de moyens, éventuellement, de commutation ou de l'usine de mise en œuvre qui commence à gonfler le code. Si vous disposez d'un véritable dynamique de la situation et de ne pas l'esprit un peu de réflexion pour traiter les données que vous recevez, alors c'est parfait. Merci pour la réponse @Tim S.
OriginalL'auteur Tim S.
Vous pouvez le faire comme ceci:
... mais vous n'obtiendrez pas beaucoup à faire avec chaque élément. Vous pourriez l'appeler ToString, mais vous ne serez pas en mesure d'utiliser (par exemple)
Name
etId
directement.where T : some type
à la fin de la première ligne afin de préciser le type. À ce point, bien que, s'attend à un certain type d'interface commune serait plus logique de s'attendre à une interface. 🙂Vous ne pouvez pas utiliser
where T : some type
avec les types anonymes bien, comme ils ne pas mettre en œuvre tout type d'interface...Vous ne pouvez pas le faire, foreach exige que la variable indiqué à mettre en œuvre GetEnumerator, et les types anonymes ne garantit pas que.
Skeet: bon point, mon cerveau est insuffisante, ce matin.
Je suppose que vous pourriez utiliser la réflexion pour toujours accès/définir les propriétés si T est un type anonyme de droit? Je pense à un cas où quelqu'un écrit un "Select * from" déclaration et utilise un anonyme (ou défini) de classe pour définir les colonnes du résultat de la requête de la carte du même nom, propriétés de votre objet anonyme.
OriginalL'auteur Jon Skeet
Malheureusement, ce que vous essayez de faire est impossible. Sous le capot, la variable de requête est tapé pour être un IEnumerable d'un type anonyme. Anonyme noms de type de ne peut pas être représenté dans le code de l'utilisateur n'est donc pas un moyen de les rendre un paramètre d'entrée d'une fonction.
Votre meilleur pari est de créer un type et de l'utiliser comme retour de la requête, puis le passer à la fonction. Par exemple,
Dans ce cas, vous n'êtes que la sélection d'un champ unique, de sorte qu'il peut être plus facile de sélectionner directement le champ. Ce sera la cause de la requête à taper comme un IEnumerable du type de champ. Dans ce cas, le nom de colonne.
FYI: fusionnées à partir de stackoverflow.com/questions/775387/...
Le mot "nouveau" rend le truc arriver. Merci beaucoup...
Une mise en garde est que lorsque vous créez une classe, propre
Equals
changements de comportement. I. e. vous avez à mettre en œuvre. (Je savais de cette différence, mais tout de même réussi à oublier pendant un refactoring.)OriginalL'auteur JaredPar
Vous ne pouvez pas passer d'un type anonyme à un non générique de la fonction, sauf si le paramètre type est
object
.Les types anonymes sont destinés à court terme l'utilisation dans une méthode.
À partir de MSDN - Les Types Anonymes:
(l'emphase est mienne)
Mise à jour
Vous pouvez utiliser des génériques pour réaliser ce que vous voulez:
re
object
- oudynamic
;pSi le casting avec "comme" vous devriez vérifier si la liste est null
"peux" != "ont". À l'aide de
object
n'est pas le même que pour faire une méthode générique du type anonyme, comme par ma réponse.OriginalL'auteur Oded
Normalement, vous le faites avec les médicaments génériques, par exemple:
Le compilateur doit alors en déduire la
T
lorsque vous appelezMapEntToObj(query)
. Pas tout à fait sûr de ce que vous voulez faire à l'intérieur de la méthode, donc je ne peux pas dire si c'est utile... le problème est qu'à l'intérieur deMapEntToObj
vous ne pouvez toujours pas le nom de laT
- vous pouvez soit:T
T
de faire des chosesmais autre que cela, il est assez difficile à manipuler les types anonymes - pas moins parce qu'ils sont immuables ;-p
Un autre truc (quand extraction de données) est de transmettre aussi un sélecteur à - dire quelque chose comme:
c'est vraiment pour le compilateur, car il génère. Dans VB.NET, anon-types peuvent être mutables.
FYI: fusionnées à partir de stackoverflow.com/questions/775387/...
OriginalL'auteur Marc Gravell
Vous pouvez utiliser des génériques avec l'astuce suivante (coulée de type anonyme):
OriginalL'auteur Stanislav Basovník
"dynamique" peut également être utilisé à cette fin.
OriginalL'auteur Dinesh Kumar P
Au lieu de passer d'un type anonyme, passer d'une Liste d'une dynamique de type:
var dynamicResult = anonymousQueryResult.ToList<dynamic>();
DoSomething(List<dynamic> _dynamicResult)
DoSomething(dynamicResult);
Grâce à Petar Ivanov!
OriginalL'auteur usefulBee
Si vous savez que vos résultats implémente une interface particulière vous pouvez utiliser l'interface comme type de données:
OriginalL'auteur Alex
Je voudrais utiliser
IEnumerable<object>
que le type de l'argument. Cependant pas un grand gain pour l'inévitable cast explicite.Cheers
OriginalL'auteur Mario Vernari