365

Is it possible to make this code a little more compact by somehow declaring the 2 variable inside the same using block?

using (var sr = new StringReader(content))
{
    using (var xtr = new XmlTextReader(sr))
    {
        obj = XmlSerializer.Deserialize(xtr) as TModel;
    }
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
Antony Scott
  • 21,690
  • 12
  • 62
  • 94
  • 7
    Don't use `new XmlTextReader()`. Use `XmlReader.Create()` – John Saunders Feb 22 '12 at 13:48
  • 12
    `new XmlTextReader()` has been deprecated since .NET 2.0. By using `XmlReader.Create()`, you will get the best derived `XmlReader` class possible, as opposed to just the one `XmlTextReader` class. – John Saunders Feb 22 '12 at 13:53
  • 1
    Come on, it's not like this question was about XmlTextReader specifically! Please stay on topic! – Mark Sep 15 '21 at 14:53

2 Answers2

686

The accepted way is just to chain the statements:

using (var sr = new StringReader(content))
using (var xtr = new XmlTextReader(sr))
{
    obj = XmlSerializer.Deserialize(xtr) as TModel;
}

Note that the IDE will also support this indentation, i.e. it intentionally won’t try to indent the second using statement.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Does this use the one-liner-no-braces rule to scope the statements within each other, or actually compile into some sort of chain? – ssube Feb 22 '12 at 13:50
  • @peachykeen It is a nested block but I think that in this case this is undistinguishable from a chain due to the semantics of `using` anyway. Or else I don’t understand what you mean by chain: note that in order for `using` to work properly, each resource requires its own `try`…`finally` block. – Konrad Rudolph Feb 22 '12 at 13:51
  • I see no difference between this code and the code int the question. – Mohammad Dehghan Feb 22 '12 at 13:52
  • 13
    @MD.Unicorn Yes, exactly. This is intentional – this is the most concise way C# offers: removing the parentheses and omitting the indentation. Notice how the IDE offers *explicit* support for this (otherwise it would indent the second statement). – Konrad Rudolph Feb 22 '12 at 13:53
  • 2
    @KonradRudolph My question is kind of confusing, but I'm asking if this is actually a discrete language feature designed for multiple `using`s, or just the same as `if (x) if (y) { z; }`. I think your comment answers that, though; I'm reading it as the latter? – ssube Feb 22 '12 at 14:21
  • 4
    @peachykeen Yes, it’s definitely *not* a discrete language feature, merely nested blocks. The IDE *does* treat it specially for the purpose of indentation though. – Konrad Rudolph Feb 22 '12 at 14:40
  • 1
    I'd still prefer to nest them.. I prefer indented code. Clearer to me what's being used and disposed. – Dave Lawrence Jun 14 '13 at 09:02
  • 11
    I really wish C# had a form of `using` that didn't begin a new block, but instead disposed the variables at the end of the block in which they're declared, something like: `{ using var x = new Reader(); x.Read(); }` – Stefan Dragnev Sep 05 '14 at 06:24
  • 2
    IL code still remains the same. In all two nested try finally blocks get generated in the IL code. The xtr variable which gets instantiated later gets disposed in the inner finally block and the sr variable which got instantiated before gets disposed in the outer finally block. – RBT Mar 05 '15 at 13:26
  • @StefanDragnev C# 8 (VS2019) has [something like that](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#using-declarations). – jrh Nov 13 '19 at 18:11
153

The following only works for instances of the same type! Thanks for the comments.

This sample code is from MSDN:

using (Font font3 = new Font("Arial", 10.0f), font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Frank Bollack
  • 24,478
  • 5
  • 49
  • 58