Browsing Posts published in August, 2005

Fantastic! I’ve been selected as a member of the INETA Community Launch Team for Visual Studio 2005 and SQL Server 2005! You want me to talk about cool new features in the upcoming releases? No problemo. The only question is how to cover all the new goodness that we’ll be receiving November 7? I’m sure I’ll find a way. This should be a fun next few months.

Microsoft just completed a DCR (Design Change Request) that rippled through the entirety of .NET 2.0 and will be available in the August CTP. They made Nullables truly null! Why is this a big deal? Consider the following C# code snippet running under Beta 2:


static bool IsNull<T>(T val) {
   return val == null;
}

static void Main() {
   object obj = null;
   Console.WriteLine(“obj is null: {0}”, IsNull(obj)); // Writes “obj is null: True”
   int? i = null;
   Console.WriteLine(“i is null: {0}”, i == null); // Writes “i is null: True”
   Console.WriteLine(“i is null: {0}”, IsNull(i)); // Writes “i is null: False”!
}


What the heck??? I just assigned i the value of null, a direct check confirms that it is null, but my generic method says otherwise. How can this happen? Let’s look at what is actually happening. An int? (which is just syntactic sugar for Nullable<int>) is a value-type. So when we call the generic method, our int? gets boxed. The box around the null definitely exists, which is what val == null is looking at in the generic method. Hence it returns false because the box exists, even though the value in the box is null. When you look at the code though, you don’t expect that. You expect to be examining the value.


The change in the August CTP makes the generic method work as expected for Nullable types, but it required making some fundamental changes to the CLR. Nullables are now intrinsic types and have special rules around how the runtime handles them. For instance, when boxing an int? which is null, a null is put on the heap, not a box containing null. Hence the above code works. You can also unbox any value-type into its Nullable equivalent. From Soma’s blog:


int x = 10;
object y = x;
int? z = (int?)y;   // In Beta 2, this throws an invalid cast exception at runtime  – not pretty


I wanted to say a big thanks to everyone at Microsoft who was involved in this change. It’s always gutwrenching to make such a sweeping change so close to shipping. I can only imagine the person-hours worth of testing that has been required to ensure that this change does not break existing code. Personally I think it’s definitely worth it. Frameworks and languages are easier to use the less baggage you have to carry around in your head. It’s great when things just work. This is an example of having your framework/language match the mental map you have in your head of how the world should work.


You can find some great information about this change on Somasegar’s and Joe Duffy’s blogs.

Microsoft just released a boatload of SharePoint templates for everything from a HelpDesk Dashboard to RFP Management to Change Management and more. 30 new templates in total with both standard SPS and custom versions. All free downloads and customizable to your needs. So if you need to set up a SPS site quickly, it’s worth taking a look.

 


I was asked recently by a colleague whether you could programmatically emit the name/value pairs of parameters in a Reporting Services report without hard-coding them. Seems like a logical thing to do. So I started digging deep into the guts of the Reporting Services object model and was sorely disappointed. I really like Reporting Services, but the object model accessible from within a report just bites. Let me explain.


When you access Parameters in a report from the Report Properties… Code… (or a custom assembly), you are actually dealing with a Microsoft.ReportingServices.ReportProcessing.ReportObjectModel.Parameters object. (The class is located in an assembly Microsoft.ReportingServices.Processing.dll, which is installed by default in C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\ReportServer\bin\.) This object exposes a string-based indexer and that’s it!


public class Parameters {
   public Parameter this[string key] {
      get {
         // code
      }
   }
}


You have to know the key (a.k.a. name of the parameter) to retrieve the parameter to get its value. There is no collection support. (i.e. No Count property and integer-based indexer or IEnumerable implementation.) Parameters is derived from System.Object rather than System.Collections.CollectionBase or something equally useful. You cannot use “foreach” or “for” to enumerate through the parameters.


So from within a report, you cannot obtain a parameter list programmatically as far as I can tell. The same applies to ReportItems and Fields. You’re really limited to creating little helper functions rather than being able to programmatically query the state of a report. How disappointing!