PDC Run Down

Well the PDC has ended and so I guess its time to reflect on stuff that has been going on this week. I guess the big news for me that I can talk about is that I'm co-authoring DevelopMentor's Guerrilla WinFX course with Jon Flanders, Dominick Baier, Pierre Nallet and Brock Allen. The first run will be on Microsoft's campus on the 7th November.

The big announcement for me was the Windows Workflow Foundation (WWF). This is an integral part of WinFX and means you'll never have to write a state machine again and can write declarative flows through processing that are managed by the workflow engine. Jon has co-authored a book on WWF.

The other technology that has caused big waves in the C# community in particular is Language Integrated Query (LINQ). This has required a bunch of extensions to the C# language  which will debut in version 3.0. LINQ as a framework works over in memory structures that implement IEnumerable<T> however its also extensible and Microsoft have provided two extensions XLinq for XML querying and DLinq for consuming database data. I love the basic Linq infrastructure and XLinq looks pretty neat. However, DLinq concerns me, automated creation of SQL has a habit of producing less than optimal SQL. Also its too easy to end up with alot of data being ripped off the database and joined on the client (this is what happens with hetrogenous joins).

Other than that, Office 12 looks pretty awesome as does the Aero Glass shell in Vista. IIS7 has made some very impressive advances in terms of allowing non-admins to administer a web site and hish modularization of previously monolithic functionality (the neat thing is you can drop features you're not using from memory for  a website so reducing the attack surface of that site.

I love VS2005!

In my Indigo work at the moment, I seem to be spending as much time in an XML editor as in a code editor (if not more sometimes). I went to a part of a config that I wanted to comment out and out of habit pressed Ctrl-K Ctrl-C ...

Wow! it worked! As in fact does Ctrl-K Ctrl-U

Hey, I don;t know this could have been in VS.NET for years for all I know but I loved it as it was just so unexpected

Web Services, Value Types and Nullable

Under .NET 1.x there was always an issue with changing webservices and value types. The problem being that if a the server side added a new value type parameter and the client didn't update, the client wouldn't send the extra information in the soap request. This meant that the web service received the packet and had to decide what to do with the new parameter. The .ASMX infrastructure decided to set the value type to its default value. Now for reference types this is not a problem because the default value for a reference is null. Value types on the other hand do not support a null value and so are zeroed.

Semantically this is fine for some situaltion and disasterous for others:


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Add(int x, int y)
  {
    return x + y;
  }
}
      

is fine if create a new version of Add by adding third param, z.


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Add(int x, int y, int z)
  {
    return x + y + z;
  }
}
      

As adding zero is a no-op. However multiplication is a very different story:


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Multiply(int x, int y)
  {
    return x * y;
  }
}
      

This breaks horribly if we add a z to the parameter list.


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Multiply(int x, int y, int z)
  {
    return x * y * z;
  }
}
      

This version always returns zero. This issue is one of the biggest web service interop problems that .NET faces as Simon Fell points out.

Today I was teaching the web service module of Essential .NET 2 and stumbled upon something I hadn't realised.

As you probably know by now, .NET 2.0 introduces generic types. Now as you can probably imagine generics and web services don't really mix. However one of my students asked me if using a nullable int would have worked in my multiplication example. So we tried is out and it worked! Changing the new implementation of Multiply to:


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Multiply(int x, int y, int? z)
  {
    if( z.HasValue )
      return x * y * z.Value;
    else
      return x * y;
  }
}
      

is fine as the nullable int (int?) has no value if it is not passed in the SOAP request. Looking at the wsdl, it turns out that the z parameter is now marked as nillable. So nullable types have been special cased for web services to help resolve the interop issues.

I must try out the List<> class to see if it also works ok.

Enabling the Server GC in .NET 1.1

Chris Lyon has just posted on a .NET newsgroup that you can enable the server GC by using a config file in .NET 1.1 SP1 not just Whidbey. I posted the Whidbey detail about this here

Note that the element should be gcServer (note casing)

WAHOO!!!!

Generics are CLS Compliant

A while back I was bemoaning the fact that generics were not CLS compliant. However, its just been announced that they will be by Whidbey beta 2. Hooray!

Value Type Initialization Redux Redux

Just to bring this to a conclusion, Luca Bolognese (Who now stands in Eric Gunnerson's old shoes) confirmed that this was a bug and has now been fixed.

Value Type Initialization Redux

A while back I wrote a discourse on value type initialization. However, in answering a question on the Microsoft C# newsgroup I came upon a quite bizarre sitution introduced in Whidbey (.NET 2.0). Look at the following code:

class App 
{ 
  static void Main(string[] args) 
  { 
    Point p; 
    p.X = 10; 
  }
} 

struct Point 
{ 
  int x; 
  public int X 
  { 
    get{ return x; } 
    set{ x = value; } 
  }
}

This fails compilation with the error "Use of unassigned local variable p". This is expected as p.X = 10; is actually running a method under the covers and the C# compiler won't allow you to call any members of a value type until all of its data members have been explicitly initialized either by setting them all directly (only possible if they are public) or getting the compiler to emit an initobj instruction or run a constructor (see the aforementioned discourse).

Now. there is a Point class already defined in the Systerm.Drawing namespace - lets use that one instead.

using System.Drawing;

class App 
{ 
  static void Main(string[] args) 
  { 
    Point p; 
    p.X = 10; 
  }
}

This fails compilation in exactly the same way in .NET 1.x but it compiles cleanly in Whidbey! So are there special flags on System.Drawing.Point that make the C# compiler treat it differently from the custom Point class? Not that I can see from using Reflector so either I've missed something, or the compiler is special casing this type (and at least the System.Drawing.Size which I've also checked exhibits the same behavior).

I have no problem with teh C# team changing the behavior of the compiler to just allow the .locals init IL opcode to initialize a value type and not enforce greater level of stringency - in fact that might be quite neat. But to have differing behavior for system value types and custom value types is just bizarre and confusing.

Specifying the Server GC in Whidbey

One bugbear that always annoyed me in v1.x of .NET was that the only way to specify that you wanted the server GC to run for a service was to write a stub host in C++. Today I had cause to look to see if this was still the same under Whidbey and I'm happy to say it isn't. I can across this post by Chris Lyon.

The crucial bit for me is this:

<configuration>
  <runtime>
    <gcserver enabled="true" />
  </runtime>
</configuration>

Generics and CLS Compliance - Dual Interface redux?

Following a trail that led from Mark's Excellent article on System.Xml version 2.0 features to Craig's post about a comment from Ian

The gist of it is that generics are not CLS Compliant - and this kind of makes sense as it would force all .NET languages to implement consuming of generics. However, the knock on effect of this is that much of the BCL API won't benefit from genericization (I think I'll patent that word).

I think that this shows an example where components should give access to their functionality via CLS compliant methods, but also support generic methods that can be consumed more efficiently by those langauges that support them (this would remove a whole bunch of casting for thos languages). But of course you also want the assembly marked as CLS Compliant and this can be acheived via the [CLSCompliant] attribute. But his would choke on the generic bits. However you can turn off CLS compliance checking on a member by member basis like this.

using System;

[assembly: CLSCompliant(true)]
public class Foo
{
  public object Bar(Type t)
  {
    return Activator.CreateInstance(t);
  }

  [CLSCompliant(false)]
  public T Bar() where T:new()
  {
    return new T();
  }
}
So we have one version of the Bar method is for langauges that only support the CLS the other is for those that support generics.

Hmmm ... this seems strangely reminiscent of Dual Interfaces which allowed COM interafces to be both scripting language friendly (IDispatch) and also v-table bound.