2

I've found the following code in a project I'm working on and I'm curious to know if it can be written more succinctly.

using (var stream = new FileStream(CustomSettingsFile.FullName, FileMode.Open, FileAccess.Read))
{
    using (var reader = new StreamReader(stream))
    {
        var data = reader.ReadToEnd();
    }
}

Firstly, what's the benefit of using FileStream? I understand that StreamReader can take a file path directly.

using (var reader = new StreamReader(CustomSettingsFile.FullName))
{
    var data = reader.ReadToEnd();
}

Secondly, if I'm only using the reader once, can't I just anonymize it and omit the using?

var data = new StreamReader(CustomSettingsFile.FullName).ReadToEnd();
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Ginjitzu
  • 35
  • 6
  • 3
    `using` is the reason for auto-close. Without it you have to call `Close()`. I prefer `using`. – i486 Aug 10 '23 at 09:06
  • Does this answer your question? [When do I need the \`using\` statement for Disposable elements?](https://stackoverflow.com/questions/48530556/when-do-i-need-the-using-statement-for-disposable-elements) – JHBonarius Aug 10 '23 at 09:19
  • https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readalltext?view=net-7.0 – Hans Passant Aug 10 '23 at 09:20
  • The suggested similar question does answer the main point of my question, but Guru Stron's answer also addresses my question about succinctness, so I think that answer is worth keeping. Perhaps my question would be more valuable to future readers with a different title. Any suggestions? – Ginjitzu Aug 10 '23 at 10:29

2 Answers2

3

I'm curious to know if it can be written more succinctly.

First thing you can do in this specific case is to omit extra curly braces:

using (var stream = new FileStream(CustomSettingsFile.FullName, FileMode.Open, FileAccess.Read))
using (var reader = new StreamReader(stream))
{
    var data = reader.ReadToEnd();
}

Firstly, what's the benefit of using FileStream? I understand that StreamReader can take a file path directly.

Based on the current implementation none, except for explicitly specifying the FileMode and FileAccess, though as far as I can see StreamReader will use the same defaults.

Secondly, if I'm only using the reader once, can't I just anonymize it and omit the using?

No. You need to deterministically free the unmanaged resources when you have finished using them. General rule of thumb: If something implements IDisposable then it should be disposed (for example via using which handles exceptions).

Note that since C# 8.0 you can leverage using declarations in some cases, which will call dispose at the end of current scope:

using var reader = new StreamReader(CustomSettingsFile.FullName);
var data = reader.ReadToEnd();

Also in case when you don't actually need streaming (i.e. you need the whole data at a time) consider using File.ReadAllText which will do all the work for you.

Read also:

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
1

I'm curious to know if it can be written more succinctly.

You can use File.ReadAllText or File.ReadAllTextAsync methods instead.

They create and dispose StreamReader under the hood.

Yevhen Cherkes
  • 626
  • 7
  • 10