Je retourne la variable que je crée dans une instruction à l'aide de la déclaration à l'aide de l'instruction Utilisation (sonne drôle):
public DataTable foo () { using (DataTable properties = new DataTable()) { // do something return properties; } }
7 Réponses :
Si vous voulez le retourner, vous ne pouvez pas l'envelopper dans un vous aurez Pour l'instancier comme ceci: p> et appelez à l'aide de la déclaration code>, car une fois que vous avez quitté les accolades, il est hors de portée et est éliminé.
jetez () code> dessus ultérieurement. p> p>
Il se sent comme foo () code> ==
gesteuseDatable () code> et le bloc
à l'aide du bloc code> doit être ce qui appelle cette fonction.
Oui. Pourquoi utilisez-vous le mot-clé code> à l'aide de quelque chose que vous ne voulez pas disposer à la fin du bloc de code? P>
Le but du mot à l'aide de code> est de disposer de l'objet. p>
Oui, il le disposera - puis le retournera. C'est presque toujours une mauvaise chose à faire. P>
En fait pour DataTable code>,
Dispose code> ne fait presque jamais rien (l'exception étant si elle est reprise quelque part, IIRC), mais c'est toujours une idée généralement mauvaise. Normalement, vous devez considérer les objets disposés comme inutilisables. P>
Donc, quel serait le modèle correct pour renvoyer un objet iDisposable à partir d'une méthode sans déclenchement de l'avertissement CA2000?
@Jhonny: Je ne sais pas, pour être honnête - je n'ai pas utilisé d'analyse de code comme celui-ci. Je m'attendrais à ce qu'il y aurait un moyen de supprimer l'avertissement.
@ Jhonnyd.cano-restware - Si vous allez instancier et retourner des choses isisposables, vous devez les disposer explicitement dans votre code. Votre analyse de code "devrait" reprendre que vous le disposez manuellement.
Le point d'un bloc d'utilisation consiste à créer une portée artificielle d'une valeur / objet. Lorsque l'utilisation du bloc est terminée, l'objet est nettoyé car il n'est plus nécessaire. Si vous souhaitez vraiment retourner l'objet que vous créez, ce n'est pas un cas où vous souhaitez utiliser l'utilisation.
Cela fonctionnera simplement bien. P>
public DataTable foo () { DataTable properties = new DataTable(); // do something return properties; }
Votre code à l'aide du mot clé se développe à:
{ DataTable properties = new DataTable(); try { //do something return properties; } finally { if(properties != null) { ((IDisposable)properties).Dispose(); } } }
soi-disant, il s'agit du motif d'une méthode d'usine qui crée un objet jetable. Mais, j'ai encore vu une analyse de code se plaint de cela aussi:
Wrapper tempWrapper = null; Wrapper wrapper = null; try { tempWrapper = new Wrapper(callback); Initialize(tempWrapper); wrapper = tempWrapper; tempWrapper = null; } finally { if (tempWrapper != null) tempWrapper.Dispose(); } return wrapper;
N'est-ce pas essentiellement équivalent à un bloc de capture? Pourquoi n'écrirais-tu pas wrapper x = null; essayez {...} attraper {if (x! = null) x.dispose (); } code>. L'intention n'est pas seulement 100% plus évidente, mais évite la variable de température inutile et le nettoyage manuel.
Je ne suis pas en désaccord. Mais je viens de regarder ça récemment moi-même, pas parce que je craignais de disposer de l'objet sur l'échec, mais parce que j'essayais de trouver le modèle de code qui éliminerait l'avertissement CA2000 sans que je doive la supprimer via l'attribut. Le processus d'analyse de code vérifie spécifiquement si l'objet est disposé dans un blocage enfin en raison de la nature de la règle appliquée. Je percevoir que cette question est vraiment à propos de CA2000, pas sur la disposition d'objets.
@Juliet: La déclaration code> code> manque à une réthrow, et même avec une retirante, la sémantique n'est pas la même chose que de ne pas avoir une prise. Entre autres choses, si le block code> contient aux appels à une méthode
bla code> qui pourrait provoquer une exception, Catch-and-Rethow causera la trace de la pile de montrer le numéro de ligne de la réthrosse plutôt que l'appel à
bla code> (la trace de la pile dans
bla code> sera correcte, mais le numéro de ligne de l'appel ne sera pas).
Les autres réponses sont correctes: dès que vous quittez l'utilisation du bloc, votre objet est disposé. L'utilisation de bloc est idéale pour s'assurer qu'un objet est éliminé de manière opportune, donc si vous ne voulez pas compter sur les consommateurs de votre fonction pour vous rappeler de disposer de l'objet plus tard, vous pouvez essayer quelque chose comme ceci:
var user = GetNewUserInfo(); UsingDataContext(c => c.UserSet.Add(user));
Quoi qu'il en soit, c'est juste un mauvais design et devrait être retravaillé.