Table of Contents



Many of the .NET based code samples on PI Square and GitHub are in C#. It’s easy for a VB.NET developer to feel left out. If you’ve been following me within the past 5 years you may think that I am a heavy duty C# developer. Well, I am actually, and C# is definitely my first choice for writing applications. However, I do have a fondness for VB as I started out with Visual Basic 3 in the mid-1990’s and was able to eek out a nice living writing for VB, VBA, and eventually VB.NET. VB helped feed and clothe my family for close to 2 decades.


Coming from VB 6, VB.NET was a natural introduction to .NET programming. But early on, I started to wean myself away from VB-centric calls and more towards .NET-centric ones. For example, I replaced VB’s MsgBox calls with .NET’s MessageBox. This transitioned me to the point where I stopped calling myself a VB developer and instead started calling myself a .NET developer because it was the .NET Framework, not the language used, that really was at the heart of my applications. After a while of doing that, I found it an easier transition to switch from VB.NET to C# than when I had switched from VB 6 to VB.NET.


There is no need to put your "VB Forever" shields up. I am not here to convince you to switch to C#. You are more than welcome to stay with VB.NET. What I am here to do is to help explain a few language specific things about C# so that it makes it easier for VB.NET coders like yourself to follow the C# examples more easily and without being stumped by some C# idiosyncrasies. To a large degree, many of our examples are fairly easy to follow. Putting aside the unsightly semi-colons and multitude of braces versus the wordiness of Visual Basic, both languages obviously have an overlapped feature set. It’s easy to understand that C#'s foreach and VB's For Each do the same thing. Likewise, both languages use similar features like Interpolated Strings, which look quite similar in either language.


This cheat sheet is to help address those few C# things that aren’t immediately translatable to VB. That way you can begin to put your focus back on PI Developer Technologies and not worry so much about a language that is foreign to you.



Logical Operators

Earlier versions of VB did not have short-circuiting but VB.NET has had it for quite a long while.




var keyword for implicitly typed variables

Many C# snippets may occasionally employ the var keyword to declare variables. For someone unfamiliar with it, they may mistakenly believe that the variable has a type of Object and may take any value of any data type (like Variant in the olden days). This is not true. With var, a variable is assigned the type from the right-hand expression, and once that type is assigned it cannot be changed. Microsoft's own recommendation is to use var when (1) the data type on the right-hand side is easily understood, or (2) if you really don't care about the type for variable with a very short scope.


var thing1 = "Hello, World!"; // always a string
var thing2 = 1; // always an Int32
var thing3 = 1.0; // always a Double
var thing4 = 1.0F; // always a Single


The equivalent code in VB.NET would be:


Dim thing1 = “Hello, World!”; ' always a string
Dim thing2 = 1; ' always an Int32
Dim thing3 = 1.0; ' always a Double
Dim thing4 = 1.0F; ' always a Single



Conditional Operator, or ? : operator

You may frequently see statements such as this peppered in C# code:


var lastIndex = (list != null) ? list.Count – 1 : -1;


That is to say condition ? truePart : falsePart; This is called the conditional operator. The equivalent in VB.NET would use the If operator:


Dim lastIndex = If(list != null, list.Count – 1, -1)


One should emphatically NOT use the IIf function, as it has the adverse side-effect of evaluating both the TruePart and FalsePart regardless of the condition. For example:


IIf(condition, SomeFunction1(), SomeFunction2())


Is the same as this code:


Dim truePart = SomeFunction1() ' always runs regardless of condition
Dim falsePart = SomeFunction2() ' always runs regardless of condition
If condition Then
End If


Whereas the If operator is equivalent to this bit of code:


If condition Then
' will only run if condition is True
' will only run if condition is False
End If



Null-Coalescing Operator, or ??

I personally am not a big fan of the null-coalescing operator or simply ??. It returns the left-hand operand if that operand is not null; otherwise it returns the right hand operand. The VB equivalent is also the If operator but with only 2 arguments, and the first argument must be a nullable reference type.


There is a decent explanation of how it works with VB.NET in this StackOverflow link. See the answer by Code Maverick on Dec 19, 2013.



Read-only Auto-properties (or get-only property)

C# version 6.0 introduced read-only auto-properties, which might seem odd to ponder a get-only property:


Public property AFDatabase Database { get; }


The above is equivalent to this in earlier versions of C#:


Private readonly AFDatabase _database;
Public AFDatabase Database { get { return _database; } }


In either case, the readonly property may only be assigned a value at class initialization or else within a class constructor.


The equivalent in VB.NET would be:


Private ReadOnly _database As AFDatabase
Public ReadOnly Property Database() As AFDatabase
Return _database
End Get
End Property


Note that in VB both the property - and the private backing field - must be decorated as ReadOnly.



Expression-bodied members (property => expression)

A C# expression-bodied member may work for methods as well as properties, and are best reserved for a quick one-line piece of code. Borrowing from a snippet above, an example would be:


Public AFDatabase Database => _database;


Which is the equivalent of:


Public AFDatabase Database { get { return _database; } }


However, VB.NET does not support expression-bodied members so you would have to use the more verbose VB code referenced in the previous VB example.



Remainder or Modulus operator

In VB, the Mod operator is used to find the remainder:


Dim quartile As Integer = value Mod 4


In C#, the % operator does the same thing:


int quartile = value % 4;



Integer versus Floating Point Division

In VB, the / operator will always perform floating point division, even if both operands are integers. To perform integer division with VB, one would use the \ operator.


Dim a = 5 / 2 ' a is a Double = 2.5
Dim b = 5 \ 2 ' b is an Int32 = 2


In C#, division on 2 integers always results in integer division. There is no direct equivalent to VB's \ operator. In order for floating point division to occur in C#, at least one of the operands should be a floating point value.


var a = 5 / 2; // a is an Int32 = 2 since 5 and 2 are Int32
var b = 5 / 2.0; // b is a double = 2.5 since 2.0 is a double
var c = (double)5 / 2; // c is a double = 2.5 since integer 5 is cast to double before division



The use of Lambdas

C# methods may concisely use lambdas particularly with LINQ. VB.NET requires a little more verbosity. Let’s consider an example where variable named values is an AFValues collection, and you wish to count the number of bad values.



int badCount = values.Count(x => x.IsGood == false);



Dim badCount As Integer = values.Count(Function(x) x.IsGood = False)


Let’s consider another example where 2 lambdas are needed. Let’s use LINQ to create a dictionary keyed on AFAttribute where the dictionary value is an AFValue.



AFAttributeList attrList = new AFAttributeList();
// and then you populate attrList
AFValues values = attrList.GetValue();
IDictionary<AFAttribute, AFValue> lookup = values.ToDictionary(key => key.Attribute, value => value);



Dim attrList As AFAttributeList = New AFAttributeList()
' and then you populate attrList
Dim values As AFValues = attrList.GetValue()
Dim lookup As IDictionary(Of AFAttribute, AFValue) = values.ToDictionary(Function(key) key.Attribute, Function(value) value)



Optional Parenthesis With 0 Parameters

If you use a code converter convert from C# to VB.NET, depending upon the converter of your choosing you may find many parenthesis missing in the VB.NET code. This generally occurs when no parameters are being passed. VB tries to do more for the coder than does C#. Some would suggest VB tries to do too much. Consider how C# requires the developer to know and understand cast conversions within an expression, whereas VB.NET can perform the cast conversions automatically and therefore explicit code to issue conversions is optional with VB. Likewise, VB.NET allows the parenthesis to be optional on parameter-less method calls.



A reasonable guess as to why this is allowed is that VB may be allowing you to use extension methods as a pseudo-property. The downside to this is it makes debugging a bit trickier because you may read along and think that something is a property, because it lacks parenthesis, when it is in fact a function. Plus the following just doesn’t look right to as C# coder:


foo.ToString when it really is foo.ToString()


There are no associated code examples here since it is more an artifact of the language and not a specific command of it. Suffice to say that if you are converting from C# to VB.NET, or vice versa, you will want to pay attention to anything that looks like a property, since it lacks parentheses. Some developers coding styles may allow this to remain. Others may want to explicitly insert the () to remove any doubt or confusion as to whether a call is a property or a method.



Characters to Integers and vice versa

C# has a char type and VB.NET has a Char. Both are the same thing, but how you may interact with them is quite different depending on the language. In C# a char is denoted by single quotes. In VB.NET, double quotes are used but to distinguish that the double quotes refer to a character and not a string, a lowercase c is appended following the end quote. Here is a capital A in each language:



char capitalA = 'A';



Dim capitalA As Char = "A"c



In C#, you may easily treat a char as a int or vice versa. Consider an example where you want to loop from 'A' to 'Z'.


for (int character = 'A'; character <= 'Z'; character++)


In VB.NET, the safest way to perform similar conversions requires the Microsoft.VisualBasic library be imported. This DLL provides the AscW function to safely convert a character to integer (technically it’s a Unicode code point). To convert from the integer (or Unicode code point) back to a Char, you would use the ChrW function. Here’s a VB translation of the above C# code.


For character As Integer = AscW("A") To AscW("Z")


You may ask why not just convert directly from Char to Integer or back, and note the use of “safest” or “safely”. A character is not represented just by any integer. It is a Unicode code point, and there are complications such as surrogate pairs or unprintable characters that are handled inside of AscW and ChrW.



Related Links

For additional reading, you may want to check out this comparison of language features between C# 6.0 and VB 14.


There you go. We've given a little love to our VB.NET community, which is probably larger than we think it is (you are certainly a quiet bunch). You may let me know if you liked this in comments below. Or you may comment if there are any C# translations you would like to see covered. I will be glad to add it to this page. As stated in the introduction, my intent is to empower you to read C# examples so that you are better equipped to translate to VB.