Foreach now captures variables! (Access to modified closure)

Foreach has changed in C# 5.0!

Consider the following piece of code in C# < 5.0:

public class Test
{
    public static void Main()
    {
        var words = new[] { "foo", "bar", "baz", "beer" };
        var actions = new List<Action>();
        foreach (string word in words)
        {
            actions.Add(() => Console.WriteLine(word));
        }

        actions.ForEach(e => e());
    }
}

What will this print?

Some of you will see the warning that ReSharper will print on line 9.

Access to foreach variable in closure. May have different behaviour when compiled with different versions of compiler

Notice the second sentence, and remember this warning, we’ll get back to it!

Now go ahead, try and run this in Visual Studio 2010. This will be your result:

beer beer beer beer

While I do love beer, this is not what I expect.

So how do we fix it? Well, either let ReSharper fix it (Alt+Enter -> Enter), or manual, capture the current word in a different variable:

public class Test
{
    public static void Main()
    {
        var words = new[] { "foo", "bar", "baz", "beer" };
        var actions = new List<Action>();
        foreach (string word in words)
        {
            string temp = word;
            actions.Add(() => Console.WriteLine(temp));
        }

        actions.ForEach(e => e());
    }
}

Problem solved. The code above has identical results in Visual Studio 2012.

However…

Using the first piece of code (without our temp variable) in Visual Studio 2012 the result is as follows:

foo bar baz beer

Wait what?

The compiler has changed (note that even for .NET 3.5, 4, and 4.5 in Visual Studio 2012 the 4.5 compiler is used!).

Meaning that our variable word is now declared inside of the foreach loop, and not outside.

This change can be found in the C# 5.0 spec, page 247-248, found on your machine when you’ve installed VS2012 (not Express) in: C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC#\Specifications\1033

If v was declared outside of the while loop, it would be shared among all iterations, and its value after the for loop would be the final value, 13, which is what the invocation of f would print. Instead, because each iteration has its own variable v, the one captured by f in the first iteration will continue to hold the value 7, which is what will be printed. (Note: earlier versions of C# declared v outside of the while loop.)

Note 1: read the file to get the meaning of ‘v’ and those values (like 13 and 7).
Note 2: I’ve tweeted to some guys to get the spec online.

While this is not necessarily a problem for projects coming from 2010 and upgrading to 2012, it can be an issue when you are doing round-tripping, for example in mixed teams. Developers using 2012 need to use the old behavior.

Worse, your build system is not at 2012 yet, so your result are different!

Watch out for this!

Have a good one,

-Kristof

Your project dependencies matter (when using NuGet)

At work we had the following issue, we had a Silverlight project consuming some NuGet package, this project was being exposed in a Web application.

In order to keep our solution clean – we didn’t want an ‘assemblies’ folder – we used NuGet package restore.

We did it like the book said, don’t check in the packages folder, enable NuGet package restore, add the required repositories to the nuget.targets, you know the drill.

When building locally we didn’t have any issues. Everybody was able to run the project perfectly. The packages were downloaded from the repository when unavailable locally.

The issue rose when we committed our code to our source control system and ran builds of it with MSBuild.

In order to explain my issue I managed to create a very simple test case.

I created a solution with 2 projects, a web project, and a Silverlight project.

Solution window

The NuGetTest.Client had a NuGet reference to the package ‘MvvmLight’.

When you commit code to source control and run builds of it with MSBuild, it is supposed to download the NuGet package, and then build of that.

However, if we invoke the build we are presented with the following error:

Ugh, error.

What? Why?

So I went to check the packages folder on the Build location:

It's there!

It’s there! How could it not find the dll?

Time to dig deeper.

The command line executed for the project was simple:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /nologo /noconsolelogger "C:\Builds\1\NuGetTest\New Build Definition 1\Sources\Dev\NuGetTest.sln" /m:1 /fl /flp:"logfile=C:\Builds\1\NuGetTest\New Build Definition 1\Sources\Dev\NuGetTest.log;encoding=Unicode;verbosity=diagnostic" /p:SkipInvalidConfigurations=true  /p:OutDir="C:\Builds\1\NuGetTest\New Build Definition 1\Binaries\\" /p:VCBuildOverride="C:\Builds\1\NuGetTest\New Build Definition 1\Sources\Dev\NuGetTest.sln.vsprops"  /dl:WorkflowCentralLogger,"C:\Program Files\Microsoft Team Foundation Server 2010\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Diagnostic;BuildUri=vstfs:///Build/Build/8;InformationNodeId=622;TargetsNotLogged=GetNativeManifest,GetCopyToOutputDirectoryItems,GetTargetPath;TFSUrl=http://localhost:8080/tfs/DefaultCollection;"*WorkflowForwardingLogger,"C:\Program Files\Microsoft Team Foundation Server 2010\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Diagnostic;"

I slimmed it down to the real deal (removed logging), and ended up with this:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe "C:\Builds\1\NuGetTest\New Build Definition 1\Sources\Dev\NuGetTest.sln" /m:1 /p:SkipInvalidConfigurations=true

Now I download the latest version of the project locally, and execute that command line:

"d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.sln" (default target) (1) ->"d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Host\NuGetTest.Host.csproj" (default target) (2) ->"d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Client\NuGetTest.Client.csproj" (default target) (3:2) ->(CoreCompile target) ->  ViewModel\MainViewModel.cs(1,7): error CS0246: The type or namespace name 'GalaSoft' could not be found (are you missing a using directive or an assembly reference?) [d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Client\NuGetTest.Client.csproj]  ViewModel\MainViewModel.cs(17,34):errorCS0246: The type or namespace name 'ViewModelBase' could not be found (are you missing a using directive or an assembly reference?) [d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Client\NuGetTest.Client.csproj]  ViewModel\ViewModelLocator.cs(15,7): error CS0246: The type or namespace name 'GalaSoft' could not be found (are you missing a using directive or an assemblyreference?)[d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Client\NuGetTest.Client.csproj]

 

And we’re greeted with a lot of text, and at the end the same error. So it’s not the user that executes the build (he has sufficient rights).

What seems to happen here?

If we check the log we can see that the NuGetTest.Client is built because NuGetTest.Host depends on it:

Project "d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Host\NuGetTest.Host.csproj" (2) is building "d:\Personal\Documents\Visual Studio 2010\Projects\NuGetTest\NuGetTest.Client\NuGetTest.Client.csproj" (3) on node 1 (GetXapOutputFile target(s)).

If we then continue reading the log file we can see that NuGet’s RestorePackages task is only executed after this task, which results in MSBuild trying to build the Silverlight project before all the required assemblies are downloaded.

How can we solve this? We can specify that the Silverlight project should be built before the web project, and thus forcing the RestorePackages to execute in order (before the build of the Silverlight project).

We can do this by going to project dependencies in the Solution Explorer, just do a right mouse on your solution and go to “Properties”.

In that window go to “Project Dependencies”:

Properties for solution, build order

In the “Project” dropdown you select your host project (here “NuGetTest.Host”), and check the checkbox of every Silverlight Project it depends on. This will make MSBuild explicitly build that project before continuing to the web project.

Good luck & have a good one!

Team Foundation 2010: Associate work item with changeset AFTER check in.

Today I was struggling associating a work item with a changeset after a check in. There is however no options for this in the UI. Or is there? Let’s check:

Cannot edit work items from changeset window

Ok, so not through the changeset UI.

Let’s check the command line.

c:Program Files (x86)Microsoft Visual Studio 10.0VC>tf changeset /?
TF - Team Foundation Version Control Tool, Version 10.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Displays information about a changeset and lets you change the associated
attributes, such as comments and check-in notes.

tf changeset [/comment:("comment"|@commentfile)]
             [/notes:("NoteFieldName"="NoteFieldValue"|@notefile)] [/noprompt]
             [/collection:TeamProjectCollectionUrl]
             [changesetnumber | /latest] [/login:username,[password]]

(emphasis mine).

So not through the command line. Now what? Let’s think: we want to associate a changeset with a work item. Why not look the other way around?

After the successful commit remember the changeset # (in our example 25464), go to the work item you want to associate the changeset to.

Right bottom you’ll see a tab called ‘Links’ (1), click it, and then click the ‘Link to’ (2) button.

Associate work item with changeset

In the next window, select ‘Changeset’ (1) and enter the number in the box (2). Hit  ‘OK’ (3).

Associate part II

After that hit ‘CTR+S’ to save your work item.

After that go back to your changeset:

It's there!

It works!

Have a good one!

-Kristof

Stopping Casini before (re)building website in Visual Studio

Hi ya’ll,

I sometimes use Casini to debug local web applications. Casini is easy to configure, no need to create a virtual directory, it’s gone after you close Visual Studio so it’s easy.

The problem is that sometimes when changing some code, Casini’s caches aren’t cleared. So you get a stale version of your webpage (or Silverlight or …).

While playing with Powershell I found a little gem called Stop-Process. It even accepts wildcards! Which is nice, since there are 2 WebDev.Webservers. One for .NET 2.0 and one for .NET 4.0.

How can we link this to Visual Studio? Easy. Go to your web project and double-click properties:

Double-click properties

Then go to Build Events, and enter the following text in the Pre-Build event command line (as shown on the picture):

powershell Stop-Process -name webdev.webserver*

Build Events

Next time when you rebuild, Casini will be stopped, and you will always start from a clean page 🙂

Enjoy.

-Kristof

Visual Studio 2010 PowerTools

Hi All,

Since I’ve installed Visual Studio 2010 PowerTools I’ve had the following problem:

Entering shift+enter didn’t break the line anymore.

This is because of the autocomplete braces function of the PowerTools.

You can disable this function by clicking Options in the Tools Menu:

Tools > Options

And then click ‘Productivity Power Tools’ on the left:

Productivity Power Tools options

In that window set ‘Automatic Brace Completion’ to ‘Off’.

Now restart your Visual Studio 2010 (Important!)

Unfortunately this doesn’t restore the shortcut in the keyboard settings of Visual Studio 2010.

To fix this go to your keyboard settings in Visual Studio 2010:

Edit.BreakLine

And enter this string in the search box: ‘Edit.BreakLine’ (without the quotes).

As you can see only ‘Enter’ is mapped to BreakLine.

Now set focus to the ‘Press shortcut keys’ textbox and press Shift+Enter. And then hit Assign.

This is the end result:

Set Shift+Enter to Edit.BreakLine

There we go 🙂

Take it easy,

Kristof

Visual Studio 2010 Pro Power Tools and closing square bracket problem on AZERTY

There seems to be a problem with the default keyboard mapping of the so called ‘Align Assignments’ found in the Visual Studio 2010 Pro Power Tools.

The default shortcut is mapped to Control + Alt + ]. While this is not a problem on a QWERTY these keystrokes are used to type a square bracket on a AZERTY keyboard:

Azerty keyboard

As you can see the character on the lower right corner needs to be accessed with Ctrl + Alt + key or the Alt Gr + key. This way you trigger the ‘Edit.AlignAssignments’ on your keyboard. Thus the ‘]’ doesn’t appears on screen, it merely aligns the current line.

Edit.AlignAssignments shortcut

Solution: remove or remap the shortcut.

Thanks to Gill Cleeren for pointing out this problem.

Dispose and Finalizing, done the right way

I created this class to make life a little bit easier for me.

You are free to use it as you wish!

How to use:

Override this class, override ReleaseManaged() and ReleaseUnmanaged() with the appropriate code, and you are good to go.

namespace SuperDisposeImplementation
{
    using System;

    /// <summary>
    /// Override this class for easy releasing of managed and unmanaged code.
    /// </summary>
    /// <remarks>
    /// By Kristof Mattei
    /// Use as you wish
    /// I don't hold the copyright
    /// Combined from code I found everywhere.
    /// </remarks>
    public abstract class SuperDispose : IDisposable
    {
        /// <summary>
        /// True if managed resources are already cleaned up, false if not
        /// </summary>
        private bool _disposed;

        #region IDisposable Members

        /// <summary>
        /// Implementation of IDisposable.Dispose(). Don't make virtual
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

        #endregion

        /// <summary>
        /// Dispose(bool disposing) executes in two distinct scenarios.
        /// If disposing equals true, the method has been called directly
        /// or indirectly by a user's code. Managed and unmanaged resources
        /// can be disposed.
        /// If disposing equals false, the method has been called by the
        /// runtime from inside the finalizer and you should not reference
        /// other objects. Only unmanaged resources can be disposed.
        /// </summary>
        /// <param name="disposing">True when called from the Dispose, false when called from the ~. Don't call yourself</param>
        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this._disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    this.ReleaseManaged();
                }

                // Dispose unmanaged resources.
                this.ReleaseUnmanaged();

                // disposing has been done, make sure we don't dispose the managed ones again.
                this._disposed = true;
            }
        }

        /// <summary>
        /// Override this method, and release unmanaged resources in that method
        /// </summary>
        protected abstract void ReleaseUnmanaged();

        /// <summary>
        /// Override this method, and release managed resources in that method
        /// </summary>
        protected abstract void ReleaseManaged();


        /// <summary>
        /// Use C# destructor syntax for finalization code.
        /// This destructor will run only if the Dispose method
        /// does not get called.
        /// It gives your base class the opportunity to finalize.
        /// Do not provide destructors in types derived from this class.
        /// </summary>
        ~SuperDispose()
        {
            // make sure we don't dispose managed resources, hence the false
            // this is because we can't control the called order of 
            this.Dispose(false);
        }
    }
}

Windows Azure SDK: connecting to non SQLExpress Instance

When you want to build an Azure application, but you don’t have SQL Express installed the build action in Visual Studio will fail.

You will receive the following message in your output window:

Windows Azure Tools: Failed to initialize the Development Storage service. Unable to start Development Storage. Failed to start Development Storage: the SQL Server instance ‘localhost\SQLExpress’ could not be found. Please configure the SQL Server instance for Development Storage using the ‘DSInit’ utility in the Windows Azure SDK.

To fix this you open the Windows Azure SDK Command Prompt:

Windows Azure SDK Command Prompt

And enter the following text:

dsinit /sqlinstance:.

dsinit /sqlinstance:.

This will cause Azure to use the default instance (with no name). You can switch this to whatever you like, just replace the . (dot) by the appropriate MS SQL instance.

The result will look like this:

Development Storage Initialization

Good luck, happy coding.

LINQ to Entities: EntityReference

When creating one to many relationships one might bump into the following problem:

Consider the following database design:

Tables:

Customers
-Id
-FirstName
-LastName
-…snip…
-City

Cities
-Id
-Name
-Zip

With a many to one relation from Customers.City to Cities.Id

While this is easy to do in SQL, the LINQ to Entities syntax might seem a bit different.

Consider the following piece of code:

City c = (from city in ctx.CitySet
where city.Name == cityName && city.Zip == cityZip
select city).FirstOrDefault();

This selects the city (if it exists) or null.

Now the problem is: IF the city exists, how do I point the current customer’s city to that particular city.

I tried this:

//customer is a customer object
customer.City = c;

But that resulted in duplicate cities in the database.

The solution was actually quite easy, I browsed through all the properties (Intellisense!) and found this:

customer.CityReference.EntityKey = c.EntityKey;

This resulted in the one to many relationship I had in mind. No duplicate cities in my database.

I love database normalization!