Introduction
This
is a 'kind of a' Visual Basic alternative to the original tip.
If you want to achieve the same functionality in VB as in the original C# tip, you would have to create a full iterator class. While it could be done, I started to wonder if it is feasible? Writing an iterator class is somewhat painful and maintaining it can also be a pain.
The problem is that Visual Basic doesn't currently have equivalent for yield return
command. Visual Studio 2012 will change this but since it's not published yet it's not yet a usable solution.
So, instead of creating an iterator class I ended up to a solution where the extension methods are implented using a C# assembly which is simply referenced from the Visual Basic project. Here's a picture of the project setup.
The CumulativeHelper
implemented using C# looks as following:
using System.Linq;
namespace CumulativeHelper {
public static class CumulativeHelper {
public static System.Collections.Generic.IEnumerable<string> CumulativePath(
this System.Collections.Generic.IEnumerable<string> pathPart) {
System.Text.StringBuilder concatenated = new System.Text.StringBuilder();
foreach (string part in pathPart) {
if (concatenated.Length != 0) {
concatenated.Append('\\');
}
concatenated.Append(part);
yield return concatenated.ToString();
}
}
public static System.Collections.Generic.IEnumerable<string> AllButLast(
this System.Collections.Generic.IEnumerable<string> stringItem) {
System.Text.StringBuilder concatenated = new System.Text.StringBuilder();
for (int counter = 0; counter< stringItem.Count() - 1; counter++) {
yield return stringItem.ElementAt(counter);
}
}
public static System.Collections.Generic.IEnumerable<decimal> CumulativeSum(
this System.Collections.Generic.IEnumerable<decimal> numbers) {
decimal summedNumber = 0;
foreach (decimal number in numbers) {
summedNumber = summedNumber + number;
yield return summedNumber;
}
}
}
}
The functionality is described in the original tip.
Calling from Visual Basic
So the code above handles the LINQ iteration. The Visual Basic project has a project reference to the C# assembly so the VB code can call the functionality. The code for the Visual Basic portion looks like this
Imports CumulativeHelper
Module MainModule
Sub Main()
Dim numbers As Decimal() = New Decimal() {1, 3, 5, 7, 11}
System.Diagnostics.Debug.WriteLine("The cumulative sum contains the following results")
For Each partialSum As Decimal In numbers.CumulativeSum()
System.Diagnostics.Debug.WriteLine(" - {0}", partialSum)
Next
System.Diagnostics.Debug.WriteLine("The cumulative sum total is {0}",
numbers.CumulativeSum().Last())
Dim somePath As String = "C:\Some directory\Some subdirectory\Somefile.txt"
System.Diagnostics.Debug.WriteLine("The path contains the following parts")
For Each partialPath As String In somePath.Split("\").CumulativePath()
System.Diagnostics.Debug.WriteLine(" - '{0}'", New Object() {partialPath})
Next
Dim somePath2 As String = "C:\Windows\Some non-existent directory\Some non-existent file.txt"
System.Diagnostics.Debug.WriteLine("The path parts are valid as follows")
For Each partialPath As String In somePath2.Split("\").AllButLast().CumulativePath()
System.Diagnostics.Debug.WriteLine(
" - '{0}' does exist: {1}",
partialPath,
System.IO.Directory.Exists(partialPath))
Next
End Sub
End Module
And the result from output is
The cumulative sum contains the following results
- 1
- 4
- 9
- 16
- 27
The cumulative sum total is 27
The path contains the following parts
- 'C:'
- 'C:\Some directory'
- 'C:\Some directory\Some subdirectory'
- 'C:\Some directory\Some subdirectory\Somefile.txt'
The path parts are valid as follows
- 'C:' does exist: True
- 'C:\Windows' does exist: True
- 'C:\Windows\Some non-existent directory' does exist: False
So the same results are achieved. In my opinion extending the LINQ in VB with enumerable methods, it may be much easier and clearer to use C# for the extension methods. The implementation is much smaller and more easily maintainable and I think that the C# code is quite easily understandable even with almost no experience with C# programming.
History
-
July 28, 2012: Alternative created.