VB.NET C# Comparison Cheat Sheet Part 3: Generics, Lambdas, Extensions and LINQ
The following is the third part of a cheat sheet to help give an overview of the differences in syntax between VB.NET and C#, in .NET 4.0. Most of the examples touch on much deeper concepts, so I’ve included a few references at the end to help you out! In particular, the LINQ section seems quite brief but this is mainly because the syntax is very similar between the two languages.
Part 3:
Previous parts:
In addition to these cheat sheets, you can also use Developer Fusion’s online conversion tool to make some comparisons of your own.
Generics
| VB.NET | C# |
|---|---|
Public Class GenericClass(Of T)
Public Sub GenericMethod(param As T)
Debug.WriteLine("Type = " &
param.GetType().ToString())
End Sub
End Class
|
public class GenericClass<T>
{
public void GenericMethod(T param) {
Debug.WriteLine("Type = " +
param.GetType().ToString());
}
}
|
Dim integerGeneric As New _ GenericClass(Of Integer)() ' Outputs "Type = System.Int32" integerGeneric.GenericMethod(0) |
GenericClass<int> integerGeneric = new GenericClass<int>(); // Outputs "Type = System.Int32" integerGeneric.GenericMethod(0); |
Public Class ConstrainedClass(Of T As Control) Public Sub GenericMethod(param As T) Debug.WriteLine(param.Text) End Sub End Class |
public class ConstrainedClass<T> where T : Control
{
public void GenericMethod(T param)
{
Debug.WriteLine(param.Text);
}
}
|
Dim txt As New TextBox() With {
.Text = "Hello!"
}
Dim tbGeneric As New _
ConstrainedClass(Of TextBox)
' Outputs the contents of the TextBox
tbGeneric.GenericMethod(txt)
|
TextBox txt = new TextBox() {
Text = "Hello!"
};
ConstrainedClass<TextBox> tbGeneric =
new ConstrainedClass<TextBox>();
// Outputs the contents of the TextBox
tbGeneric.GenericMethod(txt);
|
Public Class PaintMixer(Of T As IPaintColour) Public Function MixThreeColours( p1 As T, p2 As T, p3 As T) As T Return p1.Mix(p2).Mix(p3) End Sub End Class |
public class PaintMixer<T> where T : IPaintColour
{
public T MixThreeColours(T p1, T p2, T p3)
{
return p1.Mix(p2).Mix(p3);
}
}
|
Public Class ReverseSorter(Of T As List(Of Integer)) Public Sub ReverseSort(param As T) param.Sort() param.Reverse() End Sub End Class |
public class ReverseSorter<T> where T : List<int>
{
public void ReverseSort(T param)
{
param.Sort();
param.Reverse();
}
}
|
Public Class MultiConstrained(
Of T As Control,
U As {New, TextBox})
End Class
|
public class MultiConstrained<T, U>
where T : Control
where U : TextBox, new()
{
}
|
Dim genericList As List(Of Integer) |
List<int> genericList; |
Dim genericDictionary As Dictionary(Of Guid, Integer) |
Dictionary<Guid, int> genericDictionary; |
Dim genericLookup As Lookup(Of Guid, Integer) |
Lookup<Guid, int> genericLookup; |
Lambda Expressions
| VB.NET | C# |
|---|---|
Delegate Sub LogTime() Shared Sub LogTimeNow() Dim del As LogTime = _ Sub() Debug.WriteLine(DateTime.Now) del() ' This invokes the function End Sub |
delegate void LogTime();
static void LogTimeNow()
{
LogTime del =
() => Debug.WriteLine(DateTime.Now);
del(); // This invokes the function
}
|
Delegate Function StartsWith(param As String) As Boolean
Function StartsWithA(param As String) As Boolean
Dim del As StartsWith = Function(x) x.StartsWith("A")
Return del(param)
End Function
|
delegate bool StartsWith(string param);
bool StartsWithA(string param)
{
StartsWith del = x => x.StartsWith("A");
return del(param);
}
|
' Alternative to above, without using delegate variable
Function StartsWithA(param As String) As Boolean
Dim del As Func(Of String, Boolean) =
Function(x) x.StartsWith("A")
Return del(param)
End Function
|
// Alternative to above, without using delegate variable
bool StartsWithA(string param)
{
Func<string, bool> del =
x => x.StartsWith("A");
return del(param);
}
|
Dim grub As String() =
{"Mars bar", "Toffee Crisp", _
"Pork pie", "Bounty"}
Dim sweets = grub.Where( _
Function(x) x <> "Pork Pie")
|
string[] grub =
{"Mars bar", "Toffee Crisp",
"Pork pie", "Bounty"};
var sweets = grub.Where(
x => x != "Pork pie");
|
' Using del lamdba from above Dim grubBeginningWithA = grub.Where(del) |
// Using del lamdba from above var grubBeginningWithA = grub.Where(del); |
Extension methods
| VB.NET | C# |
|---|---|
' This is the definition of the extension
Imports System.Runtime.CompilerServices
Namespace CustomExtensions
Public Module StringExtensions
<Extension()>
Public Function StartsWithA(
ByVal param As String) As Boolean
Return param.StartsWith("A")
End Function
End Module
End Namespace
|
// This is the definition of the extension
namespace CustomExtensions
{
public static class StringExtensions
{
public static bool StartsWithA(this string param)
{
return param.StartsWith("A");
}
}
}
|
' Usage of the extension above
Imports CustomExtensions.StringExtensions
Public MustInherit Class MainClass
Public Shared Function StartsWithA(
param As String) As Boolean
Return param.StartsWithA()
End Function
End Class
|
// Usage of the extension above
using CustomExtensions;
public static class MainClass
{
public static bool StartsWithA(string param)
{
return param.StartsWithA();
}
}
|
Dim numbers As Integer() = {0, 1, 2, 3, 4, 5}
Dim listOfNumbers As List(Of Integer) = numbers.ToList()
|
int[] numbers = { 0, 1, 2, 3, 4, 5 };
List<int> listOfNumbers = numbers.ToList();
|
Dim first As Integer = numbers.FirstOrDefault() |
int first = numbers.FirstOrDefault(); |
LINQ
| VB.NET | C# |
|---|---|
Dim query = From n As Integer In numbers Where n > 3 Select n |
var query = from int n in numbers where n > 3 select n; |
Dim samequerywithlambda =
numbers.Where(Function(n) n > 3)
|
var samequerywithlamdba = numbers.Where(n => n > 3); |
' LINQ to XML Dim xCrisps = <Crisps> <Crisp>Ready salted</Crisp> <Crisp>Salt n vinegar</Crisp> <Crisp>Hedgehog</Crisp> </Crisps> Dim first As XElement = xCrisps.<Crisp>.FirstOrDefault() |
// LINQ to XML
XElement xCrisps = new XElement("Crisps",
new XElement("Crisp", "Ready salted"),
new XElement("Crisp", "Salt n vinegar"),
new XElement("Crisp", "Hedgehog")
);
XElement first = (from x in xCrisps.Elements()
select x).FirstOrDefault();
|
Dim hedgehog As XElement = (From x In xCrisps...<Crisp> Where x.Value = "Hedgehog" Select x).FirstOrDefault() |
XElement hedgehog =
(from x in xCrisps.Descendants("Crisp")
where x.Value == "Hedgehog"
select x).FirstOrDefault();
|
Dim lastoneis As String = (From x In xCrisps...<Crisp> Select "Last = " & x.Value).Last() |
string lastoneis =
(from x in xCrisps.Descendants("Crisp")
select "Last = " + x.Value).Last();
|
Dim txtWithFirstEntry As TextBox =
(From x In xCrisps...<Crisp>
Select New TextBox() With
{.Text = x.Value}).First()
|
TextBox txtWithFirstEntry =
(from x in xCrisps.Descendants("Crisp")
select new TextBox()
{ Text = x.Value }).First();
|
' LINQ to SQL or Entity Framework Using context As New SweetsEntities() Dim marsBarPrice As Decimal? = (From c In context.Chocolates Where c.Name = "Mars bar" Select c.Price).FirstOrDefault() End Using |
// LINQ to SQL or Entity Framework
using (SweetsEntities context = new SweetsEntities())
{
decimal? marsBarPrice =
(from Chocolate c in context.Chocolates
where c.Name == "Mars bar"
select c.Price).FirstOrDefault();
}
|
References
The following links go into a bit more depth with some of the concepts above:
- MSDN: C# Generics Programming Guide
- MSDN: Constraints on Generics
- Multiple constraints on Generics in VB.NET
- MSDN: Lambdas Programming Guide
- Generic Delegates and Lambda Expressions
- ScottGu on Extension Methods (from 2007 but concepts still relevant)
- ScottGu on LINQ to SQL (from 2007 but concepts still relevant)
- How to perform “LIKE” queries in LINQ



