2010-01-13 12 views
5

Dans l'exemple ci-dessous, le pen retourné sera-t-il détruit (éliminé) ou non?utilisation de 'using' dans .NET

' VB' 
Public Function GetPen() As System.Drawing.Pen 
    Using pen As New System.Drawing.Pen(_Color, _Width) 
    pen.DashStyle = _DashStyle 
    Return pen 
    End Using 
End Function 

// C# 
public System.Drawing.Pen GetPen() 
{ 
    using (System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width)) 
    { 
     pen.DashStyle = _DashStyle; 
     return pen; 
    } 
} 

[EDIT]

Encore une précision ... L'objet est-Pen envoyé à l'appelant de GetPen par référence ou 'cloné' comme une structure? Je sais, cela est une classe, mais avec des objets GDI je ne suis jamais sûr ...

aura-t-il être détruit (éliminés) le pen créé en GetPen() lorsque la méthode externe Éliminez son obtenu pen avec GetPen()?

+1

Qu'avez-vous trouvé arrivé quand vous essayé? – Lazarus

+0

@Lazarus: Je n'ai pas encore essayé en demandant. J'ai demandé d'abord: D – serhio

+0

après les tests: J'ai obtenu un non nul (Nothing) invalide (avec des paramètres invalides) pen ... – serhio

Répondre

3

Oui, le stylo sera éliminé. C'est vraiment une mauvaise idée cependant; vous renvoyez un stylo déjà disposé!

Ce que vous voulez faire est de supprimer l'instruction Using de GetPen. L'instruction Using doit être utilisé par les appelants GetPen:

Using pen As Pen = GetPen() 
    ''// Draw with this pen 
End Using 

ou en C#:

using(Pen pen = GetPen()) 
{ 
    // Draw with this pen 
} 

[EDIT]

Oui, une référence est renvoyée à la méthode d'appel, non une copie. C'est pourquoi si vous jetez le stylo dans GetPen, vous ne pouvez pas utiliser ce stylo dans la méthode d'appel ;-)

En raison du fait que GetPen et la méthode appelante pointent vers le même objet Pen, il vous suffit de appelez Dispose dans la méthode d'appel.

7

Oui, il sera éliminé. Vous le renvoyez alors dans un état disposé, ainsi il ne sera pas bon pour n'importe quoi. Si vous souhaitez utiliser une méthode d'usine comme celle-ci pour renvoyer une instance Pen, vous devrez vous en occuper vous-même en externe, sans utiliser un bloc using dans la méthode comme ceci.

+3

vous pouvez toujours utiliser en utilisant: 'using (Pen p = GetAPen()) {...}' – tster

6

Pen ne sera pas nécessairement collecté, mais sa méthode Dispose() sera appelée.

1

Oui, il sera éliminé.

1

Il sera automatiquement éliminé lorsque le retour est effectué. L'utilisation force l'utilisation de Dispose() implicitement

3

Le stylo sera éliminé avant de revenir. Son équivalent de

public System.Drawing.Pen GetPen() 
{ 
    try 
    { 
     System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width); 

     pen.DashStyle = _DashStyle; 
    } 
    finally 
    { 
     pen.Dispose(); 
    } 
    return pen; 

} 
+1

vous criez mettre 'System.Drawing.Pen pen' dehors Try Catch bloc :) – serhio

+0

Je ne suis pas sûr exactement à ce sujet ... La définition de la variable est dans l'instruction using, donc en fonction de l'implémentation du compilateur (que je Je ne suis pas familier avec) il peut se situer à l'intérieur ou à l'extérieur. Je peux voir comment il peut s'étendre à l'extérieur (empêcher une NRE dans le bloc finally). – Will

0

Votre objet Pen sera éliminé avant le retour se termine et vous laisser avec un objet stylo dans un état non valide.

1

Oui.

L'objet Stylo retourné sera jeté avant que l'appelant ne le reçoive.

Dans Get() méthodes de style, vous ne voulez pas faire face à la disposition des objets.Autoriser l'appelant à Disposer de l'objet APRES ils sont terminés. Je m'attendrais à ce que la fonction appelante ressemble à ceci:

using(Pen myPen = GetPen()) 
{ 
    // My code here. 
} 
0

Oui. Dans les versions C# et VB.net de votre code, la méthode .Dispose() est appelée avant que la fonction renvoie. Ce n'est pas la même chose que de le détruire (l'objet existe toujours) mais à toutes fins utiles, l'objet est inutile, parce que la ressource non managée qui l'a rendu intéressant et utile est maintenant libérée.

Le bon modèle à utiliser lors de la construction d'une ressource IDisposable dans une fonction est de revenir juste, et utiliser une déclaration à l'aide d'appeler la fonction, comme ceci:

public System.Drawing.Pen GetPen() 
{ 
    var pen = new System.Drawing.Pen(_Color, _Width)) 
    pen.DashStyle = _DashStyle; 
    return pen; 
} 

public void FunctionThatCallsGetPen() 
{ 
    using (System.Drawing.Pen pen = GetPen()) 
    { 
     //use pen here 
    } 
} 
0

à l'aide est égale à la déclaration suivante à peu près:

essayer {

 var something = new something() ; 

}

enfin {

if (something != null) 
{ something.Dispose();} 

}

1

Votre code doit être structuré différemment parce que vous retournez un objet qui est alors disposé immédiatement.

public System.Drawing.Pen GetPen() 
{ 
    System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width) 
    { 
     DashStyle = _DashStyle; 
    } 
    return pen; 
} 

ensuite appeler à l'aide:

using (System.Drawing.Pen pen = GetPen()) 
{ 
    //Do stuff with your pen... 
}