Welcome to MSDN Blogs Sign in | Join | Help

Dump Environment Folder Paths

This is just a quick snippet to dump the value of Environment.GetFolderPath for all special folders on a machine (so I don’t have to write it again next time):

public static string DumpEnvironmentPaths()
{
    var paths = Enum.GetValues(typeof(Environment.SpecialFolder))
        .Cast<Environment.SpecialFolder>()
        .Select(folder => folder + " = " + Environment.GetFolderPath(folder))
        .Aggregate((line1, line2) => line1 + Environment.NewLine + line2);
    return paths;
}

Also, I’m using the opportunity to give Rick Strahl’s CodePaste.NET service a spin: http://codepaste.net/uo7zx8.

“CodePaste.NET is a public site for pasting snippets of code and linking to them from social network sites.”

As for the code itself (envisioning potential rotten tomatoes flying my way), several things are probably worth mentioning:

  1. First, the code is written in a more functional style, being more explicit about its intent. I think it shows more clearly the input data and the output data, how the data flows and what operations are performed on the input data.
  2. Second, I have a temporary local variable instead of returning the expression immediately. This is for easier debugging, because if you don’t have a temporary variable, you won’t be able to view the return value of the method easily in the debugger. With a temporary local, you can put a breakpoint on the return statement and inspect the results of the query. Someday the tools will be improved and will allow to inspect the return value of methods.
  3. I’m using Aggregate instead of string.Join or StringBuilder because it composes better. On large data volumes, this approach is horrible because it will allocate a ridiculous amount of unnecessary intermediate strings. StringBuilder and string.Join are much more frugal in this respect, so don’t use Aggregate with strings this way. However, in this particular example, the number of strings is O(1), so I just picked the approach that composes better. Unfortunately, string.Join doesn’t compose well at all and was never intended to be used in a fluent API.
Published Sunday, September 27, 2009 11:30 PM by Kirill Osenkov
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Dump Environment Folder Paths

Monday, September 28, 2009 5:53 AM by bahbar

Regarding 2, I've been watching return values in the "autos debug window" for a while now, in native code. I'd assume it would work in c#?

(I still write the return with a local var in my own code, but I deal with a lot of code that does not follow that pattern).

# re: Dump Environment Folder Paths

Monday, September 28, 2009 7:31 AM by ravenex

I suppose you could have used another overload of Aggregate, that takes a StringBuilder as a seed? That way it still composes well, because StringBuilder.Append returns itself. Well...there's side-effect in it, but the code still shows its intents, right?

# re: Dump Environment Folder Paths

Wednesday, September 30, 2009 3:15 AM by Alois Kraus

I fail to see why this is better, shorter or event easier to read than

       public static string DumpBetter()

       {

           StringBuilder sb = new StringBuilder();

           foreach (Environment.SpecialFolder folder in Enum.GetValues(typeof(Environment.SpecialFolder)))

           {

               sb.AppendFormat("{0} = {1}{2}", folder, Environment.GetFolderPath(folder),Environment.NewLine);

           }

           return sb.ToString();

       }

I have really tried to make use of LINQ where it provides benefits compared to the existing solutions but I simply did not find this golden line in normal programming. LINQ is cool to show as an example but is too limited in normal use cases where you have to know for example which index you are in the collection.

Yours,

  Alois Kraus

# re: Dump Environment Folder Paths

Wednesday, September 30, 2009 3:23 AM by Kirill Osenkov

ravenex: yes, that would be possible.

But I'm starting to think that Alois is right, maybe everything looks like a nail to me now that I have a hammer in my hand...

Alois, I'll be frank, I don't even know what to answer. Those are two different styles of coding. I used to write code like in your example - that's one approach and there's nothing wrong with that. Now as I'm exploring new ways, I tend to write code in "my style" (see my example). I liked the second one better, but maybe I'm wrong. I'll have to think more about and possibly ask more people.

Anyway thanks for the interesting feedback! Do let me know if you have more thoughts on the subject.

Thanks,

Kirill

# re: Dump Environment Folder Paths

Wednesday, September 30, 2009 3:28 AM by Kirill Osenkov

bahbar: I checked and the autos window doesn't display anything for C# in this case... I don't know, maybe C++ has some sort of special support for viewing method return values in the debugger??! No idea.

# re: Dump Environment Folder Paths

Thursday, October 01, 2009 12:25 AM by raven

Even if you don't keep a variable to hold the return value, you can always check the registers window to get the EAX value at the end of a method. And then you'll still be able to get everything out of it in the immediate window, with the help of SOS extensions. It ain't anything close to being as convenient as using a explicit local variable, though lol

# re: Dump Environment Folder Paths

Wednesday, October 07, 2009 5:21 AM by Marcel Popescu

I would have done it a bit different - see http://codepaste.net/fzpmah - I prefer returning IEnumerable<string> and then Join-ing the strings (I have an extension method taking an IEnumerable<string> and a separator).

As for Alois' question... well, since discovering functional programming I prefer to separate ceremony from the actual algorithm, and I consider foreach to be ceremony. It's not something I insist the other programmers on my team to do, but I personally hunt all for's and foreach's in my code and try to replace them by their functional equivalent. I guess it just "feels" more natural.

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker