If you have C# 3, you don't need to write a special class to do this. Supposing you have a sequence of strings, such as a List<string>
or string[]
, anything that supports IEnumerable<string>
, called filePathCollection
, you can just use:
var prefixedPaths = filePathCollection.Select(path => baseDirectory + path);
Hey presto - you now have an IEnumerable<string>
of paths prefixed with baseDirectory
, so you can use foreach
on it, etc. We're done.
The rest of this answer is more general explanation to help you (and others) spot where this can be applied in other cases.
Select
essentially means: take this sequence of items, do something with each item and give me back a new sequence containing all the results. The "something" is specified by providing a method that accepts one parameter of the same type as stored in the old sequence, and returns any type you like, which will be the item type of the new sequence. In this case, we're not changing the item type. Also we're defining the method "in place" using a lambda:
path => baseDirectory + path
The compiler figures out that the element type of the source collection is string
, so path
is a string
- you can think of path
as playing the same role as a "loop variable" if you had to write the whole thing out yourself. And on path
we use concatenation, so the result is another string
, so the new sequence must also be IEnumerable<string>
. This is "type inference" and is an important part of how this stuff reduces the amount of code you have to write.
The other important thing happening is "closure", which is the technical name for how we make our lambda depend not only on its "open" parameter path
but also on a "closed" parameter baseDirectory
which isn't even being explicitly passed into it as a parameter. A lambda can just reach outside itself and get to the variables visible the method it is defined within. This is specifically what frees you from the need to write a constructor that takes baseDirectory
as a parameter and stores it in a _baseDirectory
field so you can use it later repeatedly in some other method.
Note that the new sequence will always be the same length as the incoming sequence. If you want to filter items out, use Where
. If you want to make a sequence longer, use SelectMany
.