Category Archives: 9400

Breaking Changes In Argument List Evaluation In C# 5.0

The C# Language Specification states on §7.5.1.2 that “(…) the expressions or variable references of an argument list are evaluated in order, from left to right (…)”.

So, when this code is compiled with the C# 4.0 compiler:

static void M(
    int x = 10,
    int y = 20,
    int z = 30)
{
    Console.WriteLine(
        "x={0}, y={1}, z={2}", x, y, z);
}

static void Main(string[] args)
{
    int a = 0;

    M(++a, z: ++a);
}


and run, this unexpected output is obtained:



x=2, y=20, z=1


In fact, fixing this compiler flaw was the cause of one of the few breaking changes introduced in C# 5.0.



Using the 5.0 compiler, the expected result is obtained:



x=1, y=20, z=2


To avoid this type of surprises, expression evaluation should be avoided in argument lists.



With this code:



int a = 0;

int i = ++a;
int j = ++a;

M(i, z: j);


the same result is obtained for both C# 4.0 and C# 5.0:



x=1, y=20, z=2

Visual Studio 2010 Service Pack 1 And .NET Framework 4.0 Update

As announced by Jason Zender in his blog post, Visual Studio 2010 Service Pack 1 is available for download for MSDN subscribers since March 8 and is available to the general public since March 10.

Brian Harry provides information related to TFS and S. "Soma" Somasegar provides information on the latest Visual Studio 2010 enhancements.

With this service pack for Visual Studio an update to the .NET Framework 4.0 is also released.

For detailed information about these releases, please refer to the corresponding KB articles:

Update:

When I was upgrading from the Beta to the final release on Windows 7 Enterprise 64bit, the instalation hanged with Returning IDCANCEL. INSTALLMESSAGE_WARNING [Warning 1946.Property ‘System.AppUserModel.ExcludeFromShowInNewInstall’ for shortcut ‘Manage Help Settings – ENU.lnk’ could not be set.]. Canceling the installation didn’t work and I had to kill the setup.exe process.

When reapplying it again, rollbacks were reported, so I reapplied it again – this time with succes.

Is Your ASP.NET Development Server Not Working?

Since Visual Studio 2005, Visual Studio comes with a development web server: the ASP.NET Development Server.

I’ve been using this web server for simple test projects since than with Visual Studio 2005 and Visual Studio 2008 in Windows XP Professional on my work laptop and Windows XP Professional, Windows Vista 64bit Ultimate and Windows 7 64bit Ultimate at my home desktop without any problems (apart the known custom identity problem, that is).

When I received my new work laptop, I installed Windows Vista 64bit Enterprise and Visual Studio 2008 and, for my surprise, the ASP.NET Development Server wasn’t working.

I started looking for differences between the laptop environment and the desktop environment and the most notorious differences were:

System

Laptop

Desktop

SKU

Windows Vista 64bit Enterprise

Windows Vista 64bit Ultimate

Joined to a Domain

Yes

No

Anti-Virus

McAffe

ESET

After asserting that no domain policies were being applied to my laptop and domain user and nothing was being logged by the ant-virus, my suspicions turned to the fact that the laptop was running an Enterprise SKU and the desktop was running an Ultimate SKU. After having problems with other applications I was sure that problem was the Enterprise SKU, but never found a solution to the problem. Because I wasn’t doing any web development at the time, I left it alone.

After upgrading to Windows 7, the problem persisted but, because I wasn’t doing any web development at the time, once again, I left it alone.

Now that I installed Visual Studio 2010 I had to solve this. After searching around forums and blogs that either didn’t offer an answer or offered very complicated workarounds that, sometimes, involved messing with the registry, I came to the conclusion that the solution is, in fact, very simple.

When Windows Vista is installed, hosts file, according to this contains this definition:

127.0.0.1       localhost
::1             localhost


This was not what I had on my laptop hosts file. What I had was this:



#127.0.0.1       localhost
#::1             localhost


I might have changed it myself, but from the amount of people that I found complaining about this problem on Windows Vista, this was probably the way it was.



The installation of Windows 7 leaves the hosts file like this:



#127.0.0.1       localhost
#::1             localhost


And although the ASP.NET Development Server works fine on Windows 7 64bit Ultimate, on Windows 7 64bit Enterprise it needs to be change to this:



127.0.0.1       localhost
::1             localhost


And I suspect it’s the same with Windows Vista 64bit Enterprise.

Visual Studio: Setting Up The Current Project And Run

When I’m building a demo solution I usually have several projects to demo different features.


When I want to run one of the projects, I have to set it as the startup project (either in the Project menu or in the context menu of the Solution Explorer for the desired project) and start it with or without debugging.


I can start any project with debugging using the context menu for that project in the Solution Explorer, but I cannot start the project without debugging.


While preparing for my session at the upcoming Microsoft TechDays 2010, I decided to work around this by creating macros to set the current project as the startup project and start the project with or without debugging:


Sub SetAsStartUpProjectAndStartWithoutDebuggingMacro()
    DTE.ExecuteCommand("Project.SetasStartUpProject")
    DTE.ExecuteCommand("Debug.StartWithoutDebugging")
End Sub

Sub SetAsStartUpProjectAndStartWithDebuggingMacro()
    DTE.ExecuteCommand("Project.SetasStartUpProject")
    DTE.Debugger.Go(False)
End Sub


And I can bind those macros to keyboard shortcuts (Shift+Alt+F5 for starting with debugging and Ctrl+Shift+Alt+F5 for starting without debugging) and add them to a toolbar.

How To Set Elements Of An Array Of A Private Type Using Visual Studio Shadows

Visual Studio uses Publicize to create accessors public for private members and types of a type.


But when you try to set elements of a private array of elements of a private type, things get complicated.


Imagine this hypothetic class to test:

public static class MyClass
{
    private static readonly MyInnerClass[] myArray = new MyInnerClass[10];

    public static bool IsEmpty()
    {
        foreach (var item in myArray)
        {
            if ((item != null) && (!string.IsNullOrEmpty(item.Field)))
            {
                return false;
            }
        }

        return true;
    }

    private class MyInnerClass
    {
        public string Field;
    }
}

If I want to write a test for the case when the array has “non empty” entries, I need to setup the array first.


Using the accessors generated by Visual Studio, I would write something like this:

[TestClass()]
public class MyClassTest
{
    [TestMethod()]
    public void IsEmpty_NotEmpty_ReturnsFalse()
    {
        for (int i = 0; i < 10; i++)
        {
            MyClass_Accessor.myArray[i] = new MyClass_Accessor.MyInnerClass { Field = i.ToString() };
        }

        bool expected = false;
        bool actual;

        actual = MyClass.IsEmpty();

        Assert.AreEqual(expected, actual);
    }
}

But the test will fail because, although the elements of the private array myArray can be read as MyClass_Accessor.MyInnerClass instances, they can’t be written as such.


To do so, the test would have to be written like this:

[TestClass()]
public class MyClassTest
{
    [TestMethod()]
    public void IsEmpty_NotEmpty_ReturnsFalse()
    {
        for (int i = 0; i < 10; i++)
        {
            MyClass_Accessor.ShadowedType.SetStaticArrayElement(“myArray”, new MyClass_Accessor.MyInnerClass { Field = i.ToString() }.Target, i);
        }

        bool expected = false;
        bool actual;

        actual = MyClass.IsEmpty();

        Assert.AreEqual(expected, actual);
    }
}

But, this way, we loose all the strong typing of the accessors because we need to write the name of the array field.


Because the accessor for the field is a property, we could write a set of extension methods that take care of getting the field name for us. Something like this:

public static class PrivateypeExtensions
{
    public static void SetStaticArrayElement<T>(this PrivateType self, Expression<Func<T[]>> expression, T value, params int[] indices)
    {
        object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value;

        self.SetStaticArrayElement(
            ((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name,
            elementValue,
            indices);
    }

    public static void SetStaticArrayElement<T>(this PrivateType self, Expression<Func<T[]>> expression, BindingFlags invokeAttr, T value, params int[] indices)
    {
        object elementValue = (value is BaseShadow) ? (value as BaseShadow).Target : value;

        self.SetStaticArrayElement(
            ((PropertyInfo)((MemberExpression)(expression.Body)).Member).Name,
            invokeAttr,
            elementValue,
            indices);
    }
}

Now, we can write the test like this:

[TestClass()]
public class MyClassTest
{
    [TestMethod()]
    public void IsEmpty_NotEmpty_ReturnsFalse()
    {
        for (int i = 0; i < 10; i++)
        {
            MyClass_Accessor.ShadowedType.SetStaticArrayElement(() => MyClass_Accessor.myArray, new MyClass_Accessor.MyInnerClass { Field = i.ToString() }, i);
        }

        bool expected = false;
        bool actual;

        actual = MyClass.IsEmpty();

        Assert.AreEqual(expected, actual);
    }
}

It’s not the same as the first form, but it’s strongly typed and we’ll get a compiler error instead of a test run error if we change the name of the myArray field.


You can find this and other tools on the PauloMorgado.TestTools on CodePlex.

The Future Of C#


If you were able to attend this session at PDC or Tech-Ed EMEA Developers, you were presented with a first class presentation of the future of C#, presented, respectively, by Anders Hejlsberg and Mads Torgersen.


For the near future (.NET 4.0) C# will have:


  • Dynamically Typed Objects
  • Optional and Named Parameters
  • Improved COM Interoperability
  • Co- and Contra-variance

A preview of the compiler as a service was shown, but that’s not for the .NET 4.0 / Visual Studio 2010 timeframe. Probably, not even for the next.


Starting with .NET 4.0, C# and Visual Basic will converge in terms of features and follow a path of co-evolution going into the future.


No! That doesn’t mean that XML literals will be in C# in a foreseeable future. What that means is that the above list also applies to Visual Basic.


Talking of Visual Basic evolution, the _ line continuation character has been retired. If you have any use for the underscore, please visit http://www.unemployedunderscores.com/.


Resources:


PDC And Tech-Ed Wrap-Up

(It might seem a bit late for this, but, lately, I’ve been having a lot on my mind. So here it goes.)

This was my first PDC. It was just as I had been told.

For those who don’t know, the PDC is all about the future. The near future (.NET 4.0 and Windows 7) and the further future (Windows Azure, “Oslo”, “Dublin”, “Geneva”).

Next year’s PDC (Yes! Apparently, there’ll be one next year) will be also held in Los Angeles from November 17 to 20, and (I suspect) will be the commercial launch of the Azure Services Platform and a better story to tell about “Oslo”.

Tech-ED EMEA Developers, on the other hand, is more about the present and the near future. But, this year, attendees were able to have a sneak peek at what had bee shown at the PDC.

Next year’s Tech-ED EMEA Developers will be held in Berlin from November 2 to 6. Probably, like in 2006, it will be the launch of .NET 4.0 and Visual Studio 2010.

And I intend to attend both.