Object Initialisers II

Following on from Gary Short‘s message from my previous post on Object Initialisers, I decided to take a screenshot of Orcas displaying the tooltips.

Screenshot of intellisense showing object initialisers in Orcas

I really have to compliment those that designed and wrote intellisense. Not only does it work with object initialisers, but it is intelligent enough to remove properties that have already be used.

NOTE: This post was rescued from the Google Cache. The original date was Sunday, 11th March 2007.

Object Initialisers I

Continuing with the language enhancements in C#3.0. This post presents the concept of object initailisation.

Say you have a class with a default constructor and lots of properties and you want to be able in initialise the object in one line but the class doesn’t support it. What you can do is use object initailisers:

So, a series of calls like this in C#2.0:

Policy p = new InsurancePolicy();
p.Id = 123;
p.GrossPremium = 100;
p.IptAmount = 10;

Could now be written as this in C#3.0:

InsurancePolicy p = new InsurancePolicy {Id = 123, GrossPremium = 100, IptAmount = 10};

You’ve probably seen something similar already with respect to declaring attributes on an assembly, class or method.

Again, like the other language features in C#3.0, this is just syntactic sugar. The compiler will output the calls in a similar way to the first (C# 2.0) example.

At the moment I can’t see this feature being useful for classes that I build myself as I have control over the class’s constructors and if needed then I can accommodate the parameters as appropriate. Also, the idea of having a single line of code with so many object initialisers in it would seem to me to be a potential source of some really ugly code.

That isn’t to say this isn’t useful for my own classes – it could be used as a way of reducing the need to provide many overloaded versions of the constructor. It would no longer be necessary to anticipate every permutation and combination of properties that are needed to initialise the object past a basic valid state. It could save quite a bit of time. However, caution would need to be exercised. Any constructor created would still need to ensure that the object was created into a valid state. Using object initialisers to initialise the object completely from scratch may not be appropriate.

Object initialisers are a tool. So long as the developer remembers to use the right tool for the right job then this new language feature can be used very effectively.

What object initialisers would be most useful for, as far as I can see, would be for existing classes where I don’t have control over their makeup. e.g. Framework classes, or classes from a third party.

NOTE: This post was rescued from the Google Cache. The original date was Saturday 10th March, 2007.


Original comments:

My first thought when seeing this code was, how will this work with Intelisense?

3/10/2007 6:54 PM | Gary Short

The demonstration that I saw at the MSDN roadshow in Glasgow earlier this week shows that it works.

I would guess that because it knows what object you are instantiating as it comes directly after the new keyword it will be able to determine what public properties with setters are available.

3/10/2007 7:05 PM | Colin Angus Mackay

Cool, thanks for the info Colin!

3/10/2007 7:09 PM | Gary Short

Yep – with the March CTP intellisense for object initialization works great.

Hope this helps,

Scott

3/10/2007 11:33 PM | scottgu

A start on LINQ

I was at the Microsoft MSDN Roadshow today and I got to see some of the latest technologies being demonstrated for the first time and I’m impressed.

Daniel Moth’s presentation on the Language Enhancements and LINQ was exceptional – It really made me want to be able to use that technology now.

What was interesting was that the new enhancements don’t require a new version of the CLR to be installed. It still uses the Version 2.0 CLR. It works by adding additional stuff to the .NET Framework (this is .NET Framework 3.5) and through a new compiler (the C# 3.0 compiler). The C# 3.0 compiler produces IL that runs against CLR 2.0. In essence, the new language enhancements are compiler tricks, which is why the CLR doesn’t need to be upgraded. Confused yet?

Now that the version numbers of the various components are diverging it is going to make things slightly more complex. So here is a handy cheat sheet:

2002 2003 2005 2006 2007ish
Tool VS.NET 2002 VS.NET 2003 VS 2005 VS 2005
+ Extension
“Orcas”
Language (C#) v1.0 v1.1 v2.0 v2.0 v3.0
Framework v1.0 v1.1 v2.0 v3.0 v3.5
Engine (CLR) v1.0 v1.1 v2.0 v2.0 v2.0

The rest of Daniel’s talk was incredibly densely packed with information. Suffice to say, at the moment, LINQ is going to provide some excellent and powerful features, however, it will also make it very easy to produce code that is very inefficient if wielded without understanding the consequences. The same can be said of just about any language construct, but LINQ does do a remarkable amount in the background.

After the session I was speaking with Daniel and we discussed the power of the feature and he said that, since C#3.0 produces IL2.0 it is possible to use existing tools, such as Lutz Roeder’s Reflector, to see exactly what is happening under the hood. An examination of that will yield a better understanding of how LINQ code is compiler.

LINQ code looks similar to SQL. For example:

var result =
    from p in Process.GetProcesses()
    where p.Threads.Count > 6
    orderby p.ProcessName descending
    select p

This allows the developer to write set based operations in C# a lot more easily than before. A rough equivalent in C# 2.0 to do the same thing would probably look something like this:

List<Process> result = new List<Process>();
foreach(Process p in Process.GetProcesses)
{
    if (p.Threads.Count > 6)
        result.Add(p);
}
result.Sort(new DescendingProcessNameComparer());

* NOTE: Assumes that DescendingProcessNameComparer is an existing comparer that compares two Process objects by their name in descending order.

C# 3.0 introduces the var keyword. This is unlike var in javascript or VB. It is not a variant type. It is strongly typed and the compiler will complain if it is used incorrectly. For example:

var i = 5;
i = "five"; // This will produce a compiler error because i is an integer

In short this was only a fraction of what I learned from just one session – I’ll continue the update as I can.

Tags:

NOTE: This post was rescued from the Google Cache. The original date was Monday, 5th March 2007.


Original comments:

Glad you enjoyed it Colin 🙂

Be sure to check out the written version of my talk on my blog!

3/6/2007 11:34 AM | Daniel Moth

Automatic Properties

Continuing my look at the new features found in the C# 3.0 compiler I will look at Automatic Properties.

public class Employee{    public string FirstName { get; set; }
    public string Surname { get; set; }
    public DateTime DateOfBirth { get; set; }
    public Employee Manager { get; set; }}

At first look this might seem more like a definition for an interface, but for the class keyword and the member visibility modifiers.

However, this is actually a new feature where by the compiler will automatically fill in the member fields. This is useful for situations where nothing needs to be done when getting or setting values from the member fields. It means they can be constructed much more quickly as there is no need for tedious creating of private member fields then the public properties. All that is needed is one simple construct.

It is also possible to reduce the visibility of the getter and setter independently. For example, in the above example you may wish to make DateOfBirth to be effectively read-only for all by the class that owns it. You can prefix the set keyword with the private visibility modifier.

But what is the compiler actually producing? The following is the output from Lutz Roeder’s Reflector for the DateOfBirth property:

[CompilerGenerated]
private DateTime <>k__AutomaticallyGeneratedPropertyField2;

public DateTime DateOfBirth
{
    [CompilerGenerated]
    get
    {
        return this.<>k__AutomaticallyGeneratedPropertyField2;
    }
    private [CompilerGenerated]
    set
    {
        this.<>k__AutomaticallyGeneratedPropertyField2 = value;
    }
}

In the code, only the  property is accessible. Attempting to use the compiler generated name produces a compiler error.

If the full name (as shown above) is used then the compiler will complain with three errors:

Compiler errors
# Error File Row Col Project
1 Identifier expected ConsoleApplication2Employee.cs 20 18 ConsoleApplication2
2 Invalid expression term ‘>’ ConsoleApplication2Employee.cs 20 19 ConsoleApplication2
3 ; expected ConsoleApplication2Employee.cs 20 20 ConsoleApplication2

If the <> are removed the message changes to

Compiler errors
# Error File Row Col Project
1 ‘ConsoleApplication2.Employee’ does not contain a definition for ‘k__AutomaticallyGeneratedPropertyField2’ and no extension method ‘k__AutomaticallyGeneratedPropertyField2’ accepting a first argument of type ‘ConsoleApplication2.Employee’ could be found (are you missing a using directive or an assembly reference?) ConsoleApplication2Employee.cs 20 18 ConsoleApplication2

So, why go to all this trouble? Surely it isn’t just to save a few key strokes?

Part of the answer can be seen in a post I made in November 2005: Why make fields in a class private, why not just make them public? and there was a follow up in June 2006 when I returned to The Public Fields Debate Again.

In short, public fields and public properties, although they appear to look identical to the outside in C# are sytactically different once compiled. Automatic Properties are a way to address that. If you, at some point in the future, decide that you need the property to do more then the external interface of the object won’t change, you just turn the automatic property into a normal property/field combination again.

NOTE: This post was rescued from the Google Cache. The original date was Tuesday, 13th March, 2007.

Extensions Methods

I’ve been looking at more of the language enhancements in C# 3.0. In this post I’m going to look at Extensions.

There have been many times went a class has needed to be extended, but the additional code just doesn’t sit right on the class itself. In that case a utility or helper class is created to help carry out these mundane tasks without impacting the main class the helper operates on. It may be because the method requires access to classes that would tightly couple the main class to others.

It is important to remember that the extension method, like any method on a helper or utility class, cannot access the private or protected members of the class it is helping.

For example, take the children’s game Fizz-Buzz which seems to be undergoing a resurgence at the moment. The rules for the method are simple. The program counts from 1 to 100 replacing any value that is divisible by 3 with Fizz and any value that is divisible by 5 with Buzz. If a value happens to be divisible by both 3 and 5 then the output is FizzBuzz. For any other value the number is output.

First here is the version without the extensions:

public static class FizzBuzzHelper
{
    public static string FizzBuzz(int number)
    {
        if ((number % 5) == 0)
        {
            if ((number % 3) == 0)
                return "FizzBuzz";
            return "Buzz";
        }
        if ((number % 3) == 0)
        {
            return "Fizz";
        }
        return number.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        for (int i = 1; i <= 100; i++)
        {
            Console.WriteLine(FizzBuzzHelper.FizzBuzz(i));
        }
        Console.ReadLine();
    }
}

And now the version with the extensions:

public static class FizzBuzzHelper
{
    public static string FizzBuzz(this int number)
    {
        if ((number % 5) == 0)
        {
            if ((number % 3) == 0)
                return "FizzBuzz";
            return "Buzz";
        }
        if ((number % 3) == 0)
        {
            return "Fizz";
        }
        return number.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        for (int i = 1; i <= 100; i++)
        {
            Console.WriteLine(i.FizzBuzz());
        }
        Console.ReadLine();
    }
}

There aren’t actually that many changes (and the example is somewhat trivial).

First, in the extension method, the this keyword is placed before the parameter. It indicates that the extension will go on the int (or rather the Int32) class.

Second, when the extension method is called there is no reference to the utility class. It is simply called as it it were a method on the class (in this case Int32). Also, note that the parameter is not needed because it is implied by the object on which the extension method is applied.

Lutz Roeder’s reflector is already conversant with extension methods so the compiler trickery cannot be seen in the C# view of the method. However, the IL reveals that deep down it is just making the call as before. The following is the extension version:

L_0007: call string ConsoleApplication3.FizzBuzzHelper::FizzBuzz(int32)
L_000c: call void [mscorlib]System.Console::WriteLine(string)

And this is the old-style helper method call:

L_0007: call string ConsoleApplication3.FizzBuzzHelper::FizzBuzz(int32)
L_000c: call void [mscorlib]System.Console::WriteLine(string)

They are identical. So, how does the compiler tell what it needs to be doing?

The method header for the regular helper method:

.method public hidebysig static string FizzBuzz(int32 number) cil managed
{

The method header for the extension method:

.method public hidebysig static string FizzBuzz(int32 number) cil managed { .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()

And that’s it. C# just hides the need for the ExtensionAttribute. In VB the attribute needs to be explicitly declared on the method.

Intellisense also helps out with extensions. Each extension method appears in the intellisense on the object it is extending. To ensure that the developer is aware that it is an extension the icon in the list has a blue arrow and the tool tip is prefixed with “(extension)”

orcas-extensions-intellisense

It is also possible to create extension methods that take more than one parameter. For example:

public static class PasswordHashHelper
{
    public static byte[] HashPassword(this string password, byte[] salt)
    {
        // Implementation here
    }
}

It is important to note that the this modifier can only be placed on the first parameter. To do otherwise would generate the compiler error “Method ‘{method name}’ has a parameter modifier ‘this’ which is not on the first parameter”

The above multi parameter extension method can then be used like this:

byte[] hashedPassword = plainTextPassword.HashPassword(salt);

NOTE: This entry was rescued from the Google Cache. The original date was Thursday, 15th March, 2007.

Anonymous Types

Anonymous Types are another new feature to the C# 3.0 compiler.

To create one, just supply the new keyword without a class name, followed by the, also new, object initialiser notation.

As the type name is not known it needs to be assigned to a variable declared with the local variable type inference, var, keyword.

For example:

var anonType = new { FirstName = "Colin", MiddleName = "Angus", Surname = "Mackay" };

It is possible to assign a new object to the variable, but it must be created with the object initialisers in exactly the same order. If, say, the following is attempted a compiler error will be generated:

anonType = new {Surname = "Rowling",  FirstName = "Joanna", MiddleName = "Kathleen" };

The corresponding compiler error is: Cannot implicitly convert type ‘anonymous type […ProjectsConsoleApplication4ConsoleApplication4PropertiesAssemblyInfo.cs]’ to ‘anonymous type […ProjectsConsoleApplication4ConsoleApplication4PropertiesAssemblyInfo.cs]’

At the moment I’m not entirely sure where AssemblyInfo.cs comes in. If anyone knows the answer I’d love to know.

Back to the original example. What does this look like under the microscope of Lutz Roeder’s Reflector?

var <>g__initLocal0 = new <>f__AnonymousType0();
<>g__initLocal0.FirstName = "Colin";
<>g__initLocal0.MiddleName = "Angus";
<>g__initLocal0.Surname = "Mackay";
var anonType = <>g__initLocal0;

But that isn’t all that was generated. The compiler also generated the following internal class (Note: Some of the detail has been stripped for clarity)

internal sealed class <>f__AnonymousType0<<>j__AnonymousTypeTypeParameter1,
    <>j__AnonymousTypeTypeParameter2, <>j__AnonymousTypeTypeParameter3>
{
    // Fields
    private <>j__AnonymousTypeTypeParameter1 <>i__AnonymousTypeField4;
    private <>j__AnonymousTypeTypeParameter2 <>i__AnonymousTypeField5;
    private <>j__AnonymousTypeTypeParameter3 <>i__AnonymousTypeField6;

    public <>j__AnonymousTypeTypeParameter1 FirstName
    {
        get
        {
            return this.<>i__AnonymousTypeField4;
        }
        set
        {
            this.<>i__AnonymousTypeField4 = value;
        }
    }

    public <>j__AnonymousTypeTypeParameter2 MiddleName
    {
        get
        {
            return this.<>i__AnonymousTypeField5;
        }
        set
        {
            this.<>i__AnonymousTypeField5 = value;
        }
    }

    public <>j__AnonymousTypeTypeParameter3 Surname
    {
        get
        {
            return this.<>i__AnonymousTypeField6;
        }
        set
        {
            this.<>i__AnonymousTypeField6 = value;
        }
    }
}

Because the developer has no access to the actual type name the an object created as an anonymous type cannot be passed around the program unless it is cast to an object, the base class of all things. It cannot, for obvious reasons, be cast back again. So at this point the only way of accessing the data stored within is via reflection, or with methods already present on object.

Anonymous types can be examined in the debugger quite easily and show us just like any other object.

Debugging anonymous types in Orcas

One especially neat feature of anonymous types is its ability to infer a name when none is given. For example:

DateTime dateOfBirth = new DateTime(1759, 1, 25);
var anonType = new { FirstName = "Robert", Surname = "Burns", dateOfBirth };

The dateOfBirth entry was not explicitly given a name on the anonymous type. However, the compiler inferred a name based on the variable name that was given. The anonymous type therefore looks like this: { FirstName = Robert, Surname = Burns, dateOfBirth = 25/01/1759 00:00:00 }

Naturally, some will dislike this as the anonymous type now has a mix of pascal and camel case for the properties it is exposing.

NOTE: This post was rescued from the Google Cache. The orginal date was Saturday, 17th March, 2007

Because you have a passion for it

A thread recenly appeared on Code Project from a new author. He was put off by the apparent low votes he received for his article on C# Coding Standards. The article itself wasn’t too bad for a first attempt and a number of the regulars attempted to offer suggestions and to encourage him. The best comment, in my opinion, came from Marc Clifton, His advice was “Never write for other people. Write for yourself, because you have a passion for it.”

NOTE: This entry was rescued from the Google Cache. The original date was Sunday, 8th April, 2007

To Blog or Not To Blog

The BBC has an article about companies letting their staff blog, or not, entitled Companies urged: “Let your staff blog”.

Personally, I don’t blog about the place where I work. I rarely mention it at all. On the odd occasion where I have mentioned work situations it has always been well in the past and always been as anonymous as I can make it. It is possible that a person who was there will recognise the situation, but no one else.

The bottom line is that I don’t know where I’d be if the company I work for banned blogging. I mostly blog about software development and events that I am organising or going to, so it isn’t something that would really impact the company I currently work for anyway.

NOTE: This was rescued from the Google Cache. The original date was Sunday, 8th April, 2007


Original comments:

Yeah, same here. IMHO, it’s sort of an obvious choice – if talking about sensitive internal topics is forbidden, surely blogging about them is as well!

4/8/2007 9:08 PM | Shog9

 

I work for a company that is growing quickly, and is in the public eye.
If I were to blog something positive about it, there would be multiple people who will come along and complain about their bad experience.
Even if satisfied customers outnumber the disgruntled ones by 10:1, the disgruntled ones will blog about it 5:1 over the satisfied customers.
Therefore, the company has a very strict policy not to blog about the company — even with wonderful, positive comments. “No good deed goes unpunished.”

4/10/2007 5:13 PM | LJ

 

Well, I’m happy to live with the restriction about not blogging about the company while I’m employed by them. But it it were banned outright, even about Scottish Developer events I’m organising or some new fascinating feature in Orcas then I’d be really upset.

4/10/2007 6:03 PM | Colin Angus Mackay
 
 

How to ask a question

You may have noticed the odd rant now and again when I get frustrated at people on forums who need help but seem incapable of doing even the tiniest thing to help themselves in the first place. If you haven’t and are sufficiently voyeuristic here are a selection:

Well, now I have  a solution in the form of a link to a Microsoft Knowledge Base article. It is clear, it is polite, and it tells people almost everything they need to do in order to obtain free help from forums.

And here it is: How to ask a question

NOTE: This was rescued from the Google cache. The original date was Tuesday, 10th April, 2007.

Got Vista Installed

I’ve finally installed Vista on my PC! It wasn’t a trouble free installation though.

IT is always good to have a clean out of old stuff from time to time, so I took this opporunity to blow away the cobwebs of my old XP installation so during the installation I reformatted the partition where my XP installation was and started everything from scratch.

Unfortunately the installation only got so far before it just quit.  Basically, the installation has to reboot a few times during the install and on the first reboot it got itself into a bit of a fankle and just quit. When I tried to reboot again it gave me the option of booting into safe mode. So, I tried that and it said that it couldn’t continue the installation in safe mode.

A friend of mine , John Thomson, runs Roundtrip Solutions (an IT support company) and I emailed him just in case he’d heard anything about this. After checking the usual things (I have an ATI Radeon 9700 PRO graphics card) he suggested that my second monitor might be confusing it and that I should unplug it for the installation. So, I did that and the installation got further than before.

My next problem was that it obviously checks the capabilities of the hardware and sent a signal to my monitor (a Philips Brilliance 200W) that the monitor couldn’t cope with. The monitor detects this and puts up a wee message to say that it can’t cope with the signal and what its display capabilities are. Unfortunately it doesn’t remove the message once the signal has been corrected. I thought that the installation had messed up again.

So, a new attempt at installation was made, but this time I’d discovered that I have to “reboot” the monitor, so to speak. When the invalid signal came through I turned the monitor off and waited a few seconds before turning it on again. It came back to live and the installation continued without any more problems.

Once installation had completed I plugged the second monitor in again and extended the desktop to it. It works fine now. I’ve got the fireworks at the end of a winning game of Mahjong playing on the second monitor, Media Player playing my CD collection (which took about 30 seconds to reimport from my second hard disk). Shortly I’ll be installing Visual Studio and Office – Then we’ll see just how much stuff this can cope with at once. While I was running Windows XP it was typical for me to have a dozen web pages open, an Office application or two, Visual Studio 2005, Media Player, countless explorer windows and goodness knows what else running.

Tags:

NOTE: This entry was resued from the Google Cache. The original date was Saturday, 14th April, 2007