Cleaning MsBuild ItemGroup Includes

Here's a neat solution (that I totally stole from Sayed Ibrahim Hashimi ) to a problem that I sometimes run into when writing longer or multi-file msbuild scripts.

If you create an ItemGroup inside an MsBuild target:

You can then use the @(MyFiles) syntax to process each of the files. Probably your expectation is that the MyFiles collection only includes a, b and c.

Now, if you accidently recycle the name "MyFiles", say by:

  • Adding adding a new ItemGroup explicitly
  • Changing Target dependencies change the order of execution
  • Changing Target dependencies change the number of targets that are executed
  • You include a new script with a matching ItemGroup

you include you can run into trouble. You may no longer have a fresh list with just the items you think you have.

This example:

will print a.cs b.cs ... f.cs where you might be expecting only d.cs e.cs f.cs.

Sayed Ibrahim Hashimi uses a technique where the first line of the ItemGroup empties the current content (if any) then builds the list required.

Using this convention means you are always guaranteed the content of the list will be what you intended.


This technique only works if the item group is inside a target. Static item groups (what you might think of as global item groups) don't support this behaviour.