2009-05-07 4 views
4
$xml = [xml] '<node>foo</node>' 
function foo2 { return "foo2" } 

# all of these fail with the message: 
# **Cannot set "foo" because only strings can be used as values to set XmlNode properties.** 
$xml.node = foo2 
$xml.node = foo2 -as [string] # because of this issue[1] 
$xml.node = (foo2) 

# these work 
$xml.node = (foo2).tostring() 
$xml.node = (foo2) -as [string] 
$xml.node = [string] (foo2) 

# yet, these two statements return the same value 
(foo2).gettype() 
(foo2).tostring().gettype() 

1: PowerShell functions return behaviorPourquoi le mot-clé "retour" de Powershell provoque-t-il des erreurs de type?

+0

Fonctionne au moins pour moi. Aucun message d'erreur ici, ni dans Powershell 1.0 sur Vista, ni dans Powershell 2.0 dans Windows 7 RC. – Joey

+0

Fonctionne pour moi aussi. Powershell 1 et 2 sur XP. – zdan

+0

Je suis tombé sur le script où j'avais mis cette solution de contournement, et j'ai saisi l'occasion pour comprendre ce qui a causé l'erreur. C'est la déclaration "retour". –

Répondre

6

Vous avez une confirmation de l'équipe PowerShell sur celui-ci. Cela semble être un bug dans l'adaptateur XML. Si vous regardez l'objet qui est craché par foo2 dans un débogueur, c'est un objet PSObject. Si vous n'utilisez pas le mot-clé return et que vous utilisez simplement la chaîne "foo2", la fonction renvoie un objet chaîne. Le bug dans l'adaptateur XML est qu'il ne déballe pas le PSObject pour obtenir à l'objet de base. Par conséquent, lorsqu'il tente d'affecter PSObject à $ xml.node, il échoue. Pour l'instant, en guise de solution de contournement, vous pouvez déplier manuellement le psobject comme cela (ou simplement convertir en [string]):

$xml = [xml] '<node>foo</node>' 
function foo2 { return "foo2" } 
$xml.node = (foo2).psobject.baseobject 
$xml 

node 
---- 
foo2 
+0

Façon de travailler les connexions MVP, Keith :) Malheureusement, il ne me laissera pas changer ma réponse désignée, mais voici un +1 pour vous. –

+0

Pas de problème. Merci pour le vote! –

+0

Si je supprime ma réponse, cela vous permettra-t-il de réaffecter? – ShuggyCoUk

2

Selon le contexte, les fonctions peuvent retourner un tableau (de longueur 1) où le résultat attendu est à l'index 0 dans le tableau. Pour vous assurer de toujours obtenir un scalaire si un seul élément est retourné enveloppé dans un tableau, utilisez la syntaxe suivante:

$xml.node = $(myfunc) 

Hope this helps,

-Oisin

P.S. Je sais que d'autres ne peuvent pas le reprocher, et moi non plus, mais je soupçonne que votre code de démo est coupé d'un autre script plus grand.

+0

Il peut également être vrai que la fonction ne renvoie pas les chaînes, mais quelque chose d'autre qui s'affiche facilement via la sortie de PowerShell. – JasonMArcher

0

Basé sur this article Je suppose que le compilateur décide qu'il ne connaît pas le type de sortie de foo2 assez bien pour l'accepter malgré qu'il soit 'évident' que ce sera toujours une chaîne je suppose qu'il y a du code route d'ajouter quelque chose de plus à la sortie qui n'a jamais exercé ...

Mise à jour: la réponse de Keith Hill est le bon pas celui

+0

Basé sur d'autres choses que j'ai vues de Powershell (et des langages de script en général), j'ai supposé qu'il exécuterait la fonction et examinerait sa valeur de retour dynamiquement. Mais jusqu'à ce que j'entende autrement, votre réponse semble être la raison la plus probable. –

+0

Oooh vous m'a poussé sur le dessus à 10K tah :) – ShuggyCoUk

Questions connexes