Freigeben über


Req13: Catches in Using blocks

[This post is part of a series, "wish-list for future versions of VB"]

 

IDEA: Allow Catch statements in Using blocks. A Using block is just a Try/Finally block that calls "Dispose" in its destructor. It'd be handy if you could stick "Catch" statements inside the Using block as well. In other words, this code

        Using x As New C

            ....

        Catch ex As System.IO.FileFormatException

....

End Using

would be shorthand for this:

        Dim x As New C

        Try

....

Catch ex As System.IO.FileFormatException

            ....

        Finally

            If x IsNot Nothing Then

                x.Dispose()

            End If

        End Try

 

Provisional evaluation from VB team: it's a decent idea, one worth considering against the other desirable features. What do you think? Does it provide enough benefit to be worth adding to the language?

Comments

  • Anonymous
    February 15, 2010
    Should it be shorthand for Dim f = IO.File.Open(...) Try    ... Catch ex As IO.IOException    ... Finally    If f IsNot Nothing Then DirectCast(f, IDisposable).Dispose End Try or Dim f As IO.FileStream Try    f = IO.File.Open(...)    ... Catch ex As IO.IOException    ... Finally    If f IsNot Nothing Then DirectCast(f, IDisposable).Dispose End Try ? This is important difference and I vote for the second version because now catchingexceptions in Using "header" is very difficult and leads to ugly code (whole Using enclosed io Try-Catch).

  • Anonymous
    February 15, 2010
    If it isn't hard, please do this. I find myself using that pattern a lot.

  • Anonymous
    February 15, 2010
    +1 from me.. I would love to see this feature.

  • Anonymous
    February 15, 2010
    Definitely a ‘nice to have’ feature – it’s quite a common use case.

  • Anonymous
    February 15, 2010
    Yup. It's simple, logical, and reduces indentation (especially if you have multiple nested usings, and you currently are nesting those within Try/Catch blocks.

  • Anonymous
    February 16, 2010
    Back in the days when C# has "using" but VB didn't, I had hoped for this Try Using d As New DisposableObject    ... Catch ex As Exception '// Optional    ... Finally '// Optional    ... End Try To me the syntax properly indicate that the operation could fail, and if it does, we have the option to catch the exception and/or do any cleanup. The beauty of it (to me at least :-)) is we are reusing the common Try...End Try construct. Now I would consider a "Use" keyword ala F# Sub MethodA    Use d1 As New DisposableObject    ...    Try        Use d2 As New DisposableObject        ...    Catch ex As Exception        ...    Finally        ...    End Try '// d2 is disposed here End Sub '// d1 is disposed here

  • Anonymous
    February 16, 2010
    Oh.. I failed to mention both Use and Using can coexist. Given a choice between Using/Catch and Use, I'd prefer Use, as I see Using block more of a resource management construct than an error handling construct. Mixing Using/Catch and Try/Catch in the same method body probably isn't a good idea (Try Using/Catch would be a different story though :-))

  • Anonymous
    March 13, 2010
    While I don't think I'd use it all over the place, this would be a handy feature to have for those occasions when I did use it.

  • Anonymous
    April 03, 2011
    A small advantage C# has over VB with using/Using is the ability to nest multiple usings without using extra braces: using x using y using z {    // ... } Could we perhaps have an equivalent in VB? It could look like this: Using x, y, z    ' ... End Using Each "argument" would be in scope for the declaration/initialization of the next, just like with nested Usings today. The advantage would be that we could avoid three-layers deep indentation when performing a simple SQL query, for instance.

  • Anonymous
    April 03, 2011
    Hey Jeff, the syntax you ask for is ALREADY in VB! Like this: Dim request = HttpWebRequest.Create("http://microsoft.com") Using response = request.GetResponse(),    stream = response.GetResponseStream(),    reader = New StreamReader(stream)    Console.WriteLine(reader.ReadToEnd) End Using