Question LINQ funcion (C#->VB)

jclay

New member
Joined
Apr 15, 2009
Messages
2
Location
Sandpoint, ID
Programming Experience
10+
I am going through some code C# that I need to figure out how to convert to VB. I have used Tangible Softwares Instant VB and a couple of other translaters, but this chunk I am on isn't working correctly.

Here is the C# code:
VB.NET:
public static T[][] SplitInChunks<T>(T[] arr, int chunkSize)
        {
            return arr.Select((t, idx) => new { t, idx })
                .GroupBy(o => (o.idx / chunkSize), o => o.t)
                .Select(g => g.ToArray()).ToArray();
        }

This is what Intant VB is producing:
VB.NET:
Public Shared Function SplitInChunks(Of T)(ByVal arr() As T, ByVal chunkSize As Integer) As T()()
            Return arr.Select(Function(t, idx) New With {Key t, Key idx}).GroupBy(Function(o) (o.idx / chunkSize), Function(o) o.t).Select(Function(g) g.ToArray()).ToArray()
        End Function

The error that is shoing is related to the first parameter "t" in the first Function of the SELECT. It is stating:
" 't' is already declared as a type parameter of this method "

I know I know I need to learn LINQ and Lambda's, but am running up against a deparate need on this one.

Any help would be GREATLY appreciated.

Thanks,
Jim
 
T is used (as generic type parameter) and VB is case-insensitive so t is duplicate, why not try a different parameter name for the item than t, 'item' for example?

Logically SplitInChunks will not be able to fulfill its purpose, since all indexes are different the keySelector function (index / chunkSize) will return different result for all elements and no functional grouping occurs (each element goes to a group of its own), to group this function has to return same value for the elements to be grouped. One way to group in chunks is to do (index Mod chunkSize), another is (index \ chunkSize).

You don't need the 'Key' keyword in the anonymous type definition (also not in other code), no comparison is done between the elements.

As with the other code, it helps to place line feeds when doing long Linq queries like this, similar to how Sql queries are usually written. Here is the modified version:
VB.NET:
Public Shared Function SplitInChunks(Of T)(ByVal arr() As T, ByVal chunkSize As Integer) As T()()
    Return arr.Select(Function(item, idx) New With {item, idx}) _
    .GroupBy(Function(o) (o.idx Mod chunkSize), Function(o) o.item) _
    .Select(Function(g) g.ToArray()) _
    .ToArray()
End Function
 
Thanks and One More?

John,
Thanks! That really helps. I am going to have to do some serious reading up on the LINQ and Lambda thing when I have a bit of time.

As I was going through things, I found one more issue that hopefully you (or someone else) can help me with.

The code that I am going through is related to SharePoint interaction on WinForms.

So here is the other function that is giving me a hard time:

C# original:
VB.NET:
        private void EnableCheckInOutMenus(bool enable)
        {
            HashSet<string> map = new HashSet<string>(Enum.GetNames(typeof(CheckOutAction)));
            foreach (ToolStripItem it in this.contextMenuStrip1.Items.Cast<ToolStripItem>().Where(it => it.Tag != null && map.Contains(it.Tag.ToString())))
                it.Enabled = enable;
        }

Converted VB.Net
VB.NET:
        Private Sub EnableCheckInOutMenus(ByVal enable As Boolean)
            Dim map As New HashSet(Of String)(System.Enum.GetNames(GetType(CheckOutAction)))
            For Each it As ToolStripItem In Me.contextMenuStrip1.Items.Cast(Of ToolStripItem)().Where(Function(it) it.Tag IsNot Nothing AndAlso map.Contains(it.Tag.ToString()))
                it.Enabled = enable
            Next it
        End Sub

This is the error I am recieving from this code:
Overload resolution failed because no accessible 'Where' can be called with these arguments:
Extension method 'Public Function Where(predicate As System.Func(Of System.Windows.Forms.ToolStripItem, Integer, Boolean)) As System.Collections.Generic.IEnumerable(Of System.Windows.Forms.ToolStripItem)' defined in 'System.Linq.Enumerable': Nested function does not have the same signature as delegate 'System.Func(Of System.Windows.Forms.ToolStripItem, Integer, Boolean)'.
Extension method 'Public Function Where(predicate As System.Func(Of System.Windows.Forms.ToolStripItem, Boolean)) As System.Collections.Generic.IEnumerable(Of System.Windows.Forms.ToolStripItem)' defined in 'System.Linq.Enumerable': Lambda parameter 'it' hides a variable in an enclosing block, a previously defined range variable, or an implicitly declared variable in a query expression.


I really appreciate the help.

Thanks Again!!
Jim
 
Same type of parameter name clash; "For Each it As..." and "Function(it)" are two different declarations trying to use the same local scope name 'it'. Change one of them.

You can also simplify the inline function "itm.Tag IsNot ..." to just "map.Contains(CStr(itm.Tag))".

"HashSet(Of String)" can be replaced with "List(Of String)", enumerations can't have members with same name, not that it matters anyway, but you don't need that overhead.
 
Back
Top