Visual Basic 6 and LINQ
Is it possible to use LINQ and Lambda Expressions in Visual Basic 6?
One solution is to use COM Interop. When a COM client like Visual Basic 6 calls a .NET COM object, the common language run-time creates the managed object and a COM callable wrapper (CCW) for the object.
What is COM callable wrapper (CCW) ?
Code that operates within the .NET Common Language Runtime (CLR) is called managed code. This code has access to all the services that the CLR brings to the table, such as cross-language integration, security and versioning support, and garbage collection. Code that does not operate within the CLR is called unmanaged code. Because COM was designed before the CLR existed, and COM code does not operate within the infrastructure provided by the CLR, it can’t use any of the CLR services. All of your COM components are, by definition, unmanaged code.
Managed code components not only depend on the CLR, they require the components with which they interact to depend on the CLR. Because COM components don’t operate within the CLR, they are unable to call managed code components directly. The unmanaged code simply cannot reach into the CLR to directly call managed components. The way out of this dilemma is to use a proxy. In general terms, a proxy is a piece of software that accepts commands from a component, modifies them, and forwards them to another component. The particular type of proxy used in calling managed code from unmanaged code is known as a COM callable wrapper, or CCW.
If you need to use LINQ and Lambda Expressions in your Visual Basic 6 code, you can create a .NET component and expose it to the COM environment using CCW process. For creating .NET components, you can use a class library template and you need to follow the following steps to register your .NET COM for COM interop.
Step 1. With a project selected in Solution Explorer, on the Project menu, click Properties.
Step 2. Click the Compile tab in Visual Basic. Click the Build tab in C#.
Step 3. Select the Register for COM interop check box.
When you build your project, it creates a dll file together with a type library file (tlb) that COM client such as VB6 requires to establish the communication. The following example shows how to create a .NET COM with the required interfaces assuming the Register for COM interop is already checked.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Diagnostics; using System.Threading; using System.Runtime.InteropServices; namespace VB6andLINQ { [Guid("5B43FD73-4B20-40BB-A6C8-8312E5137E79")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface _BrowseDirectory { [DispId(1)] Int32 GetFilesUsingLINQ(string sourceDir); } [Guid("A2731C3E-9A90-4938-93A5-114EC61957DA")] [ClassInterface(ClassInterfaceType.None)] [ProgId("VB6andLINQ.BrowseDirectory")] public class BrowseDirectory : _BrowseDirectory { static int MatchedCount = 0; public Int32 GetFilesUsingLINQ(string sourceDir) { string[] fileNames = null; try { fileNames = Directory.GetFiles(sourceDir, "*.txt", SearchOption.AllDirectories); } catch (UnauthorizedAccessException e) { Console.WriteLine("You do not have permission to access one or more" + " folders in this directory tree."); } catch (FileNotFoundException) { Console.WriteLine("The specified directory {0} was not found.", sourceDir); } string searchTerm = "binding"; var fileContents = from file in fileNames.AsParallel() from line in File.ReadLines(file) where line.Contains(searchTerm) select new { File = file, Line = line }; try { foreach (var item in fileContents) { MatchedCount++; } } catch (AggregateException ae) { ae.Handle((ex) => { if (ex is UnauthorizedAccessException) { Console.WriteLine(ex.Message); return true; } return false; }); } Console.WriteLine("\nFound {0} match(es) for the word \"{1}\" in {2}.", MatchedCount, searchTerm, sourceDir); return MatchedCount; } } }