What a C# Coder Should Know Before They Write VB – Updated

I’ve repurposed this list and thus am making it a new post, linked from the previous. I realize this is long for a blog post, and that it changes too much, so I will be moving it to a page, once I rebuild my site (a great embarrassment).

Initially I wanted a quick list of “ways to go wrong” when switching from C# to VB. As it evolved, the line blurred between common mistakes that might make you look dumb to some rather nuanced differences between C# and VB. As Eric Meijer says – VB is not C# without semi-colons. I realized that I have crossed over into details that many VB coders do not know, at least not off the top of their head. So, I’ve shifted the target a bit. These are all things that are good to know, but this list shouldn’t scare the crap out of C# coders considering VB and VB coders may want to review it for nuances. To be clear – I didn’t sit down knowing everything in this list. I had some things around casting and tying wrong, I had completely forgotten the ! operator, and I hadn’t explored generic extension methods sufficiently.

I am sold on the concept of polyglot programming and think every C# coder should know enough VB to do Office, late binding, and XML work in VB. Assuming you keep your business logic in C#, you don’t need to know most of these details to build wrappers in VB. This list is intended for people actually building projects in VB. The framework is so core to what we do that it doesn’t make sense to demand one language or another. But if our crossing over in either direction it makes sense to embrace the elegance of the language you’re going to work in and to understand its nuances.

I’m not trying to restart any language wars, so don’t bother going there. I just want to ensure there is a good resource for C# coders that needed to write VB code.

1) Get over the respect thing or quit before you start. VB is a great language.

2) Obviously stop trying to name fields the same as properties with different casing. VB matches case to the declaration, so that’s the only place you care.

3) You type less-characters, or perhaps the same as C#. Spend enough time in the IDE with auto-complete and Intellisense to accomplish this. I’m really sorry about the Ctl-Enter thing, but you can always use a space as VB will generally remove it if it’s wrong. (By the Ctl-Enter thing, I mean that you can’t just hit Enter to accept Intellisense. You must hit Ctl-Enter, or space or some other punctuation). In addition to auto-completing structures, VB will rearrange keywords in declarations if you can’t remember whether ReadOnly comes before or after the scope.

4) VB is very good at re-indenting and re-spacing for you

5) Switch the Intellisense tab to All. Visual Basic has a Common and an All tab for Intellisense. C# does not make this distinction so the All tab is likely to be most comfortable for a C# coder. The Common tab may leave you wondering where some method or property you need is located.

6) Always turn Strict, Explicit and probably Infer On. Turn Compare to Binary although you can probably just ignore that and use the default. These are all set with Option statements at the top on. Actually, this is too strong. You may want to turn Explicit off to do late binding. As mentioned in #31 below, this is per partial class file so you can provide late binding to a fragment of your class.

7) Retrain the baby finger and ask on Connect for the IDE to remove EOL semi-colons

8) Get to know events. They are declarative with the Handles clause. Figure out that the Handles clause requires WithEvents on the variable. The common syntax for declaring events does not require the Delegate keyword:

Event MyEvent(ByVal sender As Object, ByVal args As EventArgs)

9) Learn how to use Snippets and download the Snippet Editor. Pay attention to abbreviations. Create the snippets you need. Learn to use the ?<tab> keystrokes to find templates.

VB provides a large number of snippets. It can be tedious to find the ones you use often via the menu, and unlike C# snippets don’t show up in Intellisense. Instead, use the snippet auto-complete which you access by typing the first few characters hitting ? and <tab>. This provides access to the appropriate location in an alphabetized list of snippets. In this case, Enter, as well as Ctl-Enter and whitespace punctuation will select the snippet. For a Select Case with an enum, the snippet does not fill in the values. Also, VB’s snippet expansion doesn’t access the class name, so you’ll have an extra field in dependency property snippets.

10) Take advantage of partial namespaces and aliased namespaces. Do not import classes without a good reason

11) A VB module is roughly a C# static class, except it can be used without naming the class. There is some disagreement over whether this is good. Decide and make a standard, but understand how VB uses modules

12) Spend an hour playing with nullables. VB’s comparisons approximate SQL Servers. C#’s comparisons follow different rules. This will especially bite you if you then cast to a Boolean calling null to go to False

13) VB LINQ doesn’t make you include Select. Don’t use it unless you need it. These statements are equivalent because selecting the iterator variable is inferred:

Dim kd = From s In list2
Dim kd2 = From s In list2 Select s

If you wish to select something other than the iterator variable, you can, of course, use the Select statement to define it.

14) VB LINQ has significantly more keywords making single expression LINQ statements possible and are particularly useful with aggregates, Take and Skip

15) Anonymous type mutability is flexible, while anonymous types in C# are always immutable. Explore the Key keyword, and experience creating anonymous types via LINQ and without LINQ

16) Inferred typing is as easy as in C#

17) Spend some time in casting. TryCast is pretty much the same as “as” in C#, DirectCast performs a cast only, no conversions, even widening integers, allowed. CType does a conversion or a cast. For intrinsic types, it converts. For non-intrinsic types without an overloaded CType operator, it casts and is the same as Direct Cast. If there is an overloaded CType operator that the VB compiler can resolve, CType will use that operator. C# does not have a parallel to CType, nor really one for DirectCast, since widening conversions are performed in strict cases. The parentheses cast performs some conversions, such widening integer conversions and floating point to integers, but does not perform the string to date and string to numeric conversions of VB’s CType operator. VB’s CType operator uses banker’s rounding, while the C# parentheses conversion uses simple rounding (1.5 is rounded down in C#, up in VB and in Convert.Int32, Math.Round, etc).

Initially this might be confusing, but the bottom line is you have the option of just using CType for most casting and conversions without really thinking about it, or to use DirectCast and explicit conversion operators if you want to be more explicit. The choice is yours.

To be honest, I didn’t understand all the intracacies and opinions and have updated this in every version of this post so far. I decided casting and conversions deserved their own discussion (here).

18) Understand the difference between VB operators and methods. Explore the operators, particularly the extra work done by the CType casting operator. This work is generally good for your project and it isn’t a meaningful perf hit

19) Explore all the methods and properties of the Microsoft.VisualBasic and make a team decision whether to use them. You do not have to use anything in this namespace and it is not required in all new framework implementations, although Microsoft will continue to include them. Your team might want to keep these familiar features.

20) If you use the Microsoft.VisualBasic namespace, do some perf tests on the Microsoft.VIsualBasic.Collection and consider outlawing it

21) VB uses parens for both method calls and indexes. Sorry.

22) VB uses a single equals for both comparison and assignment. It works because we can’t assign in line. Not assigning in line is good as it enforces a common best practice.

23) There’s a reason for VB’s oddly named AndAlso and your team will appreciate it. A VB 6 comparison is a binary comparison and not short-circuited. Short circuits are two lines and explicit in VB6. For consistency, And in VB.NET is binary. AndAlso is the logical comparison and is short circuited. This is consistent with C#’s & being shorter than &&. Or/OrElse parallels this.

24) Similar, for consistency with VB6, CInt (and CLng, but not CByte) in VB returns -1. This is the only case in which False equals -1. This may be important if people are doing line by line conversions because you cannot tell in VB6 whether the intent of a comparison was logical or binary.

25) Loops and conditionals do not have parentheses

26) With Option Infer On, iterator types are automatically inferred. C# requires the var keyword:

var list2 = new List<string>() { “Bill”, “Percy”, “Fred”,”George”, “Ron” };
foreach (var k in list2)
{
   // do something
}

While VB infers the type more quietly:

Dim list2 = New List(Of String)(New String() {“Fred”, “George”, “Bill”, “Percy”, “Ron”})
For Each k0 In list2
    ‘ do something
Next

27) Do loops have direct syntax for looping while and until. You can also exit from within a loop. From Help, the syntax for a Do loop is:

Do { While | Until } condition
    [ statements ]
    [ Exit Do ]
    [ statements ]
Loop

-or-

Do
    [ statements ]
    [ Exit Do ]
    [ statements ]
Loop { While | Until } condition

This does not discuss using Continue with loops. In most cases, Continue does the same thing as C# – going to the top of the next iteration and skipping any remaining statements. However, the VB Continue specifies the type of loop so if you have a single Do and For loops nested you can proceed to the next iteration of the outer loop. This is not common. Again from Help:

Continue { Do | For | While }

VB allows a simple Do Loop if you need an infinite loop (such as a wait cycle):

Do
    [ statements ]
    [ Exit Do ]
    [ statements ]
Loop

28) Check the syntax for extension methods. It follows VB’s tradition of being more explicit which will help your team make the transition. In this case, more explicit means the extension method is defined by an attribute. 

29) Get to know the With keyword. You may decide not to use it, but you should understand how to. It can significantly simplify code and because it avoids re-qualification it will also speeds up your application somewhat.

30) Get to know the ByRef/ByVal semantics. You do not specify ref on the call, only the parameter declaration

31) Get to know partial classes. You specify partial on only one class. Options are per partial, not per class, meaning you can have late binding in small portion of your class without binding overall

32) Visual Basic requires a line continuation character – the underscore. While you are typing code, you may get in the habit of including this, and certainly the compiler will catch your mistakes. However, this can be a pain when rewrapping long lines of code. Consider writing a macro to help you wrap code if this annoys you.

33) VB provides module level imports – that means you can use the same set of imports throughout your project, then add more in specific places. The default includes some I’d suggest removing, especially System.Collection (use only System.Collection.Generics

34) VB has extremely powerful features in My. Explore these and how the Intellisense experience can lead coders to do the right thing. Consider adding your own My features.

35) For WinForms code, VB has a very nice startup framework that includes things like unhandled exception that you may be doing in your C# startup routines. The VB mechanism is very strong and you probably want to use it. You can access these event from the Project Dialog

36) The targeted framework is under advanced options in the Compile tab of Project dialog

37) Namespaces work differently if no namespace is defined. In C# the class goes into the default namespace. In VB, the class goes into the project level namespace. If you put any namespace as the class level, its appended to the project namespace. Assuming all classes in the project are in the same namespace this is very good and flexible. However, if even one class needs to go into another namespace, you have to shift strategy and add explicit namespaces to every file.

38) Interfaces work differently. They are always explicit in VB and you can specify scope within the same declaration for the method addressed directly through the instance. You will probably get to like this very much as it makes the intent much more clear.

39) Hitting Enter on an Interface or Inherits statement creates or updates the required properties and methods. They are empty when created (no “Throw NotImplemented…”). They are not placed in their own region.

40) Refactoring in the box is limited to Symbolic Rename which works well, although simplified. No preview – but who actually previews? If you want additional refactorings, download Refactor! which is free for Visual Basic users.I understand Refactor Pro removes those pesky semi-colons you accidentally typed

41) VB has a handy “Go To Type Definition” in the right click menu. It does not have “Surround With”

42) No iterators. If you need them, consider defining the class in C#

43) While you rarely need to explore it, creating explicit event management code is available and very slick. Thanks Rocky for demanding this.

44) VB XLINQ is amazing. Learn how to use XML namespaces for Intellisense, manage XML as XML regarding missing values (this took a 40 line piece of C# code to three lines in VB, how to output XML, and how to use it as a generalized text processing tool

45) When using VB’s XLINQ for text processing, use lots of calls to embedded expressions rather than creating a monolithic statement as XML literals are still debugged on a per/statement level

46) Creating optional parameters in your new classes is probably not a good idea because it isn’t compliant with C#. Use overloads as you would in C#. However, if you are interacting with code that has optional parameters, you can ignore that Missing constant entirely. Adds a lot of clarity.

47) Consider using named arguments, particularly in dealing with Office. You need to learn this syntax anyway for attributes

48) When you declare array bounds you declare the upper limit, not the length. Thus a string of four elements is Dim x(3) As String. Note that you can include the array bound in the declaration. You can put the parentheses on either the variable name or type, but you must put them on the variable name if you are specifying the upper bound.

49) No multi-line lambdas in this version. When you need a closure, you must use a class. If you do not know how to use a class to build a closure, well, ask me and that probably deserves a blog post. VB also does not have true anonymous methods or void lambdas.

50) Read my column and Bill McCarthy’s column (I assume you were already reading Bill Wagner’s). That’s not flippant, we’re covering a lot of basics and overlooked issues, primarily the basics and details of new features

51) Yes, VB does have operator overloading

52) You do not have to repeat the declaration for new variables. Use the second syntax instead of the first:

Dim c As Customer = NewCustomer(<params>)
Dim c As New Customer(<params>)

53) Nothing is not quite the same as null. Nothing is closer to C#’s use of default. If you have a reference type, default in C# is null. Thus, Nothing is the same as null when assigned to or compared with a reference type.

54) The GetType operator in VB is roughly the same as typeof operator in C#. The TypeOf <variable> Is <typeName> is roughly the same as the is operator in C#. Is (without TypeOf) in VB is roughly the same as a == with reference types in C#. The caveat is that this forces the reference type semantics regardless of operator overloads.

55) You can include array bounds

56) Visual Basic has a Redim and Redim Preserve to re-dimension arrays. These can save you some code and possibilities for error, particularly when you use Redim Preserve to keep the currents content of your array.

57) Only use Dim within a class (where you must use it). Use scope declarations in other locations such as class level variables.

58) Visual Basic has separate operators for integer and floating point division. Integer division is \ while floating point is the traditional /. You will hurt performance if you do floating point division only to round back to an integer.

59) Visual Basic has two operators for concatenating strings. You can use either & or +, which accomplish slightly different things. & converts both operands to string via the class’s ToString method. It will not fail with null values, and will concatenate numerics, etc. The + operator must perform type checking before the concatenation and is therefore slower than the & according to MSDN

60) Do not use On Error. This is a holdover from VB6. While you can accomplish VB6-like behavior it makes for very messy and potentially slower IL, regardless of whether an exception occurs. On the other hand, if you’re desperately trying to move code into .NET, perhaps it will be a short term crutch.

61) While it may not aid readability, if you feel compelled to include multiple statements on one line, use a colon to separate them.

62) You can’t do in line assignments – a single equals is a comparison operator in these contexts. Similarly, you can’t increment and decrement in place. You can however use the increment and assign (+=), concatenate and assign (&=) and similar operators.

63) The Default keyword defines the property that is analogous to the indexer in C#. This property must have a parameter and can be accessed without specifying the property name. The following two code fragments (where list is System.Collections.Generic.List(Of T)) are identical:

X = list(42)
X = list.Item(42)

You can define default properties on your own collection classes via the Default keyword.

64) The meaning of “anonymous delegate” is different in Visual Basic and C#. In C# it’s an inline delegate. In VB it’s basically an inferred delegate (thanks to Lucian for the fragment):

Delegate Function D(ByVal x As Integer) As Integer
Dim f = Function(x As Integer) x + 1
Dim d1 As D = f   
Dim d2 As Func(Of Integer, Integer) = f 

65) Constraint syntax on generics is a little different, along with providing multiple constraints. The VB and C# syntax below are identical:

Public Class SomeClass( _
     Of T As New, _
          V As IComparable)

public class SomeClass<T, V>
         where T : new()
         where V : IComparable

and with multiple constraints:

Public Class SomeClass( _
           Of T As {BizObject, New}, _
               V As IComparable)

public class SomeClass<T, V>
       where T : BizObject, new()
       where V : IComparable

66) Starting in Visual Basic 9.0, VB does have ternary and default assignment operators. Ternary operators take three operands. The first must evaluate to a Boolean, and if true, the second value is returned. Otherwise the third value is returned. These are effectively equivalent:

If(boolValue, first, second) ‘ VB

boolValue ? first : second // C#

It’s important to note that this differs from the older IIf function. The IIf function evaluated all argument expressions regardless of the value of the Boolean. This often defeats the purpose of the ternary operator because one of the operands is invalid based on the Boolean value:

y = If(x Is Nothing, defaultValue, x.SomePropertyName)

A null coalescing operator takes two values. If the first value is not null, it is used. If the first value is null, the second argument is used. Again, this is an operator, not a method, so the second expression is not evaluated unless it is needed:

x = If(nullableInt, -1) ‘ VB

x = nullableInt ?? -1 // C#

67) VB does not have a collection initializer. You can, however, use the overload of List that takes an IList as input and still make the assignment on one line:

Dim list2 = New List(Of String)(New String() {“Fred”, “George”, “Bill”, “Percy”, “Ron”})

68) (replaced as the previous 68 fit better into #9 and I’m not going for a record here)
When passing an out or ref argument to a function, there is no call site (as in the where you make the call) indicator for the out or ref status. The indicator is only on the declaration.

69) Visual Basic and C# use the same operators in different ways. The help topic “Operators Compared in Different Languages” will help you find your favorite operator and avoid thinking VB doesn’t have a particular operator that’s been added in a recent version, such as bitwise operations. However, it has a number of inaccuracies that I’ve asked to be fixed in the on line version – they can’t be fixed locally for a while. These errors I see are

a) Visual Basic has a null coalescing operator starting with VB 9.0. This is NOT the old IIF function but a true coalescing operator.
Dim x = If(y, “Fred”)
b) Visual Basic has an exponentiation assignment operator that is missing from this list ^=
c) The equals and not equals sign work perfectly well for strings in Visual Basic (as well as C#). You may chose to use StringComp from the Visual Basic library, but that would be unusual and it is NOT an operator. When comparisons need to be locale aware, Equals works well, and for other relationships, the System.String.Compare and CompareOrdinal work well.
d) Logical operators for VB should include AndAlso and OrElse. When used with booleans, And and Or are boolean operators, so their inclusion is correct. And and Or are Bitwise operators when used with integers (at a bit level these are the same thing – flipping bits). AndAlso and OrElse are only used with booleans and always short circuit.
e) The inclusion of IIF as a ternary operator should be removed from this list. It is outdated, and not an operator. It evaluates all arguments, which makes it basically useless. The parallel to C#’s ?: operator is If starting with VB 9.0.I have no clue what a binary conditional is supposed to mean. When used with two arguments, If is a null coalescing operator per my item #1

With these corrections tattooed into your frontal lobe, the help page comparing operators becomes very useful.

A number of operators perform different operations.

&= Concatenation assignment in VB and Bitwise And assignment in C#
^= Exponentiation assignment in VB and Bitwise exclusive Or assignment in C#
& Concatenation in VB and Bitwise or Logical And in C#
^ Exponentiation in VB and Exclusive or Logical Exclusive Or in C#
! Qualification (see # 70) in VB and Bitwise or logical Not in C#

70) VB has the ! resolution operator. I’m biased against this operator, but you should know what it does if you see it in code. Given the Junk1 class:

Public Class Junk1

    Default Public ReadOnly Property Foo(ByVal s As String) As String
        Get
            If s = “Fred” Then
                Return “Flinstone”
            End If
            Return Nothing
        End Get
    End Property
End Class

The same IL results from the ! operator, the default call, or the full call.

Dim j1 As New Junk1
Dim j2 = j1!Fred
Dim j3 = j1(“Fred”)
Dim j4 = j1.Foo(“Fred”)

I am biased against this call.  First, it gives you two different syntaxes for iterators – one for numerics and one for strings. Second, it makes a string look like compile time checked code. If I search for “Fred” because I’ve made a constant or some other reasons I want to track down all occurrences, I cannot find it if I search as a string. Finally, Fred is a string, not a constant and why the heck make it easier to look good doing the wrong thing. Make the string a constant and use the second syntax.

71) C# has a single equality operator ==. VB has one for value types and strings (=) and one for reference types (Is).Similarly, C# has one inequality operator != where VB has two (<> and IsNot). This can be especially confusing with strings because either operator is valid. The Is and IsNot operator search for a location in memory while the = and <> operators compare the string:

Dim s1 = “Fred”
Dim s2 = “Freds”
s2 = s2.Substring(0, 4)
If s1 = s2 Then
    Console.WriteLine(“= works”)
End If
If s1 Is s2 Then
    Console.WriteLine(“Unexpected”)
En If

Here, “Unexpected” will not display. However, this relies on details of storage and if you simple assign s2 to the literal “Fred” it will be hit because the compiler figures out that there is only one literal. As a result, don’t use Is with strings.

72) The AddressOf operator creates a delegate on the fly:

Dim del As EventHandler(Of EventArgs) = AddressOf Button3_Click

73) VB has a scope resolution operator of MyClass. This forces the code in the current class to be run, even if an overridden virtual method would point to different code. There is no equivalent in C#. It’s rarely used, but occasionally extremely useful.

74) Use square brackets or qualification (namespace, Me, MyBase, namespace alias, etc) or square brackets when variable names are the same as keywords (often better to avoid keywords).

75) Coming out of the shadows: There are three ways in IL to provide replacement code in a derived class. These are overriding, hideBySig and shadowing by name. I need to write a separate post explaining this nuance because its widely misunderstood. But the short story is: VB overloads the meaning of Overloads to both be an occasionally necessary indicator that something is being overloaded and hide by sig, which is “new” on the method declaration in C#. VB also provides shadowing by name which is not provided by C#. When you mark a method with “Shadows” all base class method declarations with the same name, regardless of signature, is replaced with the new code. Thus you can make signatures go away. But like HideBySig, they are available if someone casts to a base class. Shadows and hide by sig nuances are not widely understood so use some care using techniques relying on this.

76) You can have a method or property in a class that matches the class name. You can’t do this in C# because you’d conflict with the constructor. The Foo class can have a method Foo, leading to Foo.Foo. Or with a nested class named foo with a shared method named Foo and a namespace named Foo you can have Foo.Foo.Foo.Foo. That’s silly, of course.

77) Visual Basic and C# infer parameters for generic extension methods differently. Visual Basic takes a two pass approach – in the first pass, the type arguments for the first (main) parameter is resolved. After this type parameter has effectively been removed from the list, any remaining type arguments are directly resolved or inferred. As a result, both of the following will work in VB:

Dim k1 = q.Test1(Of String, Int32)()
Dim k2 = q.Test2(Of String, Int32)()

Where the extension methods are:

Public Module ExtensionMethods
    <System.Runtime.CompilerServices.Extension()> _
    Public Function Test1(Of TFirst, TSecond, TResult)(ByVal list As IEnumerable(Of TSecond)) As TResult
        Return Nothing
    End Function

    <System.Runtime.CompilerServices.Extension()> _
    Public Function Test2(Of TFirst, TSecond, TResult)(ByVal list As IEnumerable(Of TFirst)) As TResult
        Return Nothing
    End Function
End Module

This allows simplification of some LINQ operators. For example:

Dim maxIndex = q.Max(Of Integer?)(Function(c) c.Credit)

Where C# requires syntax resolvable in a single pass, such as:

var maxValue = q.Max((Func<Customer, Int32?>)(cust => cust.Credit));

C# allows you to specify both type parameters on the generic method call:

maxValue = q.Max<Customer, Int32?>(cust => cust.Credit);

VB does not allow you to specify a generic type argument for a type parameter inferred from the type of the first argument, it must be inferred so you will receive a compiler error if you attempt to specify both type parameters:

Overload resolution failed because no accessible ‘Max’ accepts this number of type arguments

—————————————————————————————————————-

I still look forward to your input. It’s been a wild ride. What I thought would be a top ten list is now over 75 items and instead of an hour I have a chunk of this week in this list – made much better by the comments and suggestions I’ve received. Stupid mistakes and misunderstandings, things that bit you, etc.

Thanks to Bill McCarthy for suggesting some corrections to 17, 18 and 24 as well as pointing out something in one of his articles that led to 51.

I’ve updated this on 7/22/08 and plan to continue to update this list as people point out additional things, or I think of them. Thanks to a ton of people for their comments, including Jim Wooley, Jay B. Harlow, Lucian Wischik, Erik Meijer, Rod Stephens, Bill McCarthy, Herfried K. Wagner, Cor Ligthert, Rob Teixeira, Rocky Lhotka, Jeff Certain, Steve Smith and “NotMyself”. Also, Eric and Int19H for pointing out politely a dumb error I made yesterday in the code for 26.

20 thoughts on “What a C# Coder Should Know Before They Write VB – Updated”

  1. I changed jobs for only 10 months and was required to write in VB.NET I was able to survive but I did not enjoy it. I am glad to be back in C#.
    Two things that I think that are very good in VB.NET are #29 – With and #47 – Named Arguments.
    #1 – VB is a great language raised my blood pressure immediately. My history is Delphi 1-7 and then C#. I cannot remember how many times I wrote ActiveX controls in Delphi so the VB coders could perform some task. There were so many language things in VB6 and early that made VB an inconsistent language to program in. With VB.NET, VB is much better. Just as C# is better than Delphi. So I still have a hard time with the VB is a great language. For instance, #42 says if iterators are needed, write them in C#.

    #21 – VB uses parens for both method calls and indexes. Sorry.
    #32 – continuation character – the underscore followed by a space.
    #37 – Namespaces. VB.NET general hides them from you making things “easier” but then when programs grow in size, the developer has a new challenge.
    #41 – Missing Surround With. I use C# snippets from the IntelliSense and I use Surround With.
    #60 – On Error, glad you recommend against using it.
    The list above are just some of the things that frustrate me in VB.NET. I know this was not the purpose of your post but I would find it interesting to see what makes VB.NET coders frustrated in writing in C# and what makes C# coders frustrated in writing in VB.NET.

  2. 3) … (By the Ctl-Enter thing, I mean that you can’t just hit Enter to accept Intellisense. You must hit Ctl-Enter, or space or some other punctuation).

    Doesn’t the TAB key accept Intellisense with one key press and no side effects?

  3. @pablo,

    Yes it does, but many C# coders will be used to using enter for that same purpose, and will be frustrated by the fact that in VB pressing enter to accept Intellisense will also insert a newline.

    @Kathleen,

    “Get to know the With keyword…it will also speeds up your application somewhat.”

    I am not aware of any way that the With keyword can speed up an application. It is only a syntax shortcut. Take the following two functionally equivalent fragments:

    Dim rand As New Random()
    With rand
    Console.WriteLine(.Next(1, 6))
    Console.WriteLine(.NextDouble())
    Console.WriteLine(.Next(0, 100))
    End With

    Dim rand As New Random()
    Console.WriteLine(rand.Next(1, 6))
    Console.WriteLine(rand.NextDouble())
    Console.WriteLine(rand.Next(0, 100))

    If you look at the IL generated by a release build of these two fragments, the only difference is that the With version generates an extra local variable to store the result of the target expression (even if that expression is already a local variable). This translates to an extra reference slot on the stack and four extra IL instructions (one to initialize the extra variable, one to push it back onto the stack, and two to null it out at the end of the With block). A similar test with value types shows that the IL in that case is exactly equivalent.

    So it looks to me like With is less efficient in the case of reference types and no more efficient in the case of value types. What am I missing?

  4. David,

    Thanks for the comments. Everytime you dereference (. notation) you also take a small hit. So, when you have a long dereference list

    WhosOnFirst.NoHesOnSecond.WhatsOnThird.Fourth

    And that is repeated several times, the derferencing hit is more than the variable initizlization. At least that was documented early on the VB help. I haven’t benchmarked where the change happens.

    With would rarely be used in the kind of code you displayed, although I think I should have been more clear because my implication that it is always faster could lead someone to use it excessively.

    Kathleen

  5. > Thanks for the comments. Everytime you dereference (. notation) you also take a small hit.

    You do, but the dereference occurs when using the unary dot operator inside “With” in VB as well.

  6. I just realized I never answered this…

    Actually the With construct creates a temporary variable and uses that within the With block. The dereferencing occurs only once at the start of the block.

    Kathleen

  7. “VB infers the type more quietly:”

    Dim list2 = New List(Of String)(New String() {“Fred”, “George”, “Bill”, “Percy”, “Ron”})

    how was that more “quietly” than this?

    var list2 = new List() { “Bill”, “Percy”, “Fred”,”George”, “Ron” };

  8. I have read through competencies brought out changes a great many ideas in advance of,so authored am easiest that will aid create funding for industry experts a great number of blograisers up-to-date read along the lines of being poor quality stuff,to learn joining your downline happen to be truly, my partner and i such as scan through your good imagination,and consequently ganoderma coffee genuinely thankful so may well discover an element progressive,moreover burning off admiration your entire blogs as

  9. @Eber Irigoyen & Kathleen

    “26. VB infers the type more quietly.”

    The VB 2010 compiler infers the type of arrays quietly. You can now write:

    dim arr1() = {“Tom”, “Jerry”, “Dexter”}
    dim arr2() = {1, 2, 3, 4}
    dim arr3() = {1, 2, 3.5, 4}
    dim arr4() = {“Tom”, “Jerry”, 1, 2, 3.5}

    and have the following results:
    arr1 – String Array
    arr2 – Integer Array
    arr3 – Double Array
    arr4 – Object Array

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>