Previous month:
March 2006
Next month:
May 2006

April 2006

LINQ Part 5 - Custom Extension Methods

Part 4 of this series showed how the following query expression resolves to methods.

var winners = from r in racers
   where r.Wins > 3
   orderby r.Wins descending
   select r;

Part 5 of this series show how to use custom extension methods with query expressions.

All the parts of the query expression can be overridden with custom extension methods. The where part of the query expression resolves to the Where extension method. The following method implementation demonstrates a custom extension method to be used with objects that implement IEnumerable<Racer>:

namespace

UseCustomWhere
{
  
public static class Algorithm
  
{
     
public static IEnumerable<Racer> Where(
           
this IEnumerable<Racer> racers,
           
Func<Racer, bool> predicate)
     
{
        
foreach (Racer r in racers)
        
{
           
Console.WriteLine("checking {0}", r.Name);
           
if (predicate(r))
              
yield return r;
        
}
     
}
  
}
}

An extension method is a static method that requires the this keyword with the first parameter. This way every object of type of the first parameter can be used to invoke the method. A previous example of an extension method demonstrated an extension to the String class.

Extension methods don't break access rules of object-orientation. Extension methods are just a different way to invoke static methods. The extension method does not have access to private or protected member of the class that is extended.

To use the extension method from the query expression, the method just has to be brought into the scope. Opening the namespace (in the example UseCustomWhere), uses the extension method Where with the query expression.

Christian


LINQ vs. XQuery

Recently I found an XQuery sample application that I had written for a beta version of .NET 2.0. The XQueryCommand class didn't make it to the release of .NET 2.0.

The current status of the XQuery specification is candidate recommendation (since 3-Nov-2005).

What's the difference between XQuery and LINQ?

In a previous blog post I've shown how to filter and sort using LINQ:

var winners = from r in racers
   where r.Wins > 3
   orderby r.Wins descending
   select r;

How can the same be fulfilled with XQuery?

for $racer in doc("racers.xml")/Racers/Racer
  where $racer/Wins > 3
  order by $racer/Wins descending
  return $racer

The syntax doesn't look that different. So what are the big differences between XQuery and LINQ?

  • XQuery is specified by the W3C.
  • LINQ is defined by Microsoft.
  • LINQ is integrated with .NET languages.
  • XQuery requires a separate parser.
  • XQuery is a query language for XML data.
  • LINQ can be extended by custom methods written in a .NET language.
  • LINQ is independent of the data and supports the same syntax for objects, database access, and XML.

In my opinion, having one syntax to query objects, the database, and XML is a really big advantage.

Christian

Via Don: Michael Kay's comparison of XSLT 2.0 and XQuery.


C++/CLI, Finalize and Dispose

C++/CLI has a great syntax for dealing with resources. The syntax of C++/CLI is simpler than C#.

To implement the interface IDisposable, with C# this syntax is needed:

// C#
public class Resource : IDisposable
{
   public void Dispose()
   {
      Console.WriteLine("release resource");
   }
}

C++/CLI is using the destructor syntax to implement the interface IDisposable:

// C++/CLI
public ref class Resource
{
public:
   ~Resource()
   {
      Console::WriteLine("release resource");
   }
};

If the Resource class allocates native resources, the Finalize method of the base class should be overridden. With C# the Finalize method is overridden using a destructor syntax:

// C#
public class Resource : IDisposable
{
   ~Resource()
   {
      Dispose();
   }


   public void Dispose()
   {
      Console.WriteLine("release resource");
   }
}

C++/CLI already uses the destructor syntax to implement IDisposable. To implement the Finalize method, a new syntax is available:

// C++/CLI
public ref class Resource
{
public:
   ~Resource()
   {
      this->!Resource();
   }
protected:
   !Resource()
   {
      Console::WriteLine("release resource");
   }

};

If the Resource class contains embedded objects that should be disposed, this pattern is needed with C#:

// C#
public class Resource : IDisposable
{
   private EmbeddedResource embedded;

   public Resource()
   {
      Console.WriteLine("allocating resource");
      embedded = new EmbeddedResource();
   }


   ~Resource()
   {
      Dispose(false);
   }

   protected virtual void Dispose(bool disposing)
   {
      Console.WriteLine("release resource");
      if (disposing)
      {
         embedded.Dispose();
      }
   }


   public void Dispose()
   {
      Dispose(true);
   }
}

This pattern is already implemented with ~Resource and !Resource:

// C++/CLI
public ref class Resource
{
private:
   EmbeddedResource^ embedded;
public:
   Resource()
   {
      embedded = gcnew EmbeddedResource();
   }
   ~Resource()
   {
      delete embedded;
      this->!Resource();
   }
protected:
   !Resource()
   {
      Console::WriteLine("release resource");
   }
};

C++/CLI also has advantages using and releasing the Resource class. With C#, the Dispose method can be invoked directly:

// C#
Resource r = new Resource();
r.Foo();
r.Dispose();

This is similar to the following C++/CLI constructs. The C++ delete gets compiled to invoking the Dispose method:

// C++/CLI
Resource^ r = gcnew Resource();
r->Foo();
delete r;

With both of these usages it was not taken into account that the Foo method may throw an exception, and thus the Dispose method is not invoked. C# has the using statement for dealing with this easily. At the end of the using scope, Dispose is invoked.

// C#
using (Resource r = new Resource())
{
   r.Foo();
}

Instead of the using statement, C++/CLI allows declaring the object locally. The object is still allocated on the managed heap. However, when the object gets out of scope, the Dispose method is invoked. This is simpler than the C# using statement.

// C++/CLI
Resource r;
r.Foo();

Christian