What statements do you not write in vb.net because they are difficult to scan for meaning? And what do you write instead? - vb.net

This should be a community wiki question.
I've had to work with a lot of vb.net lately, and recently created the following expression.
If If(report.IsPublicReport, False) Then Return True
Now, this is a simple coalesce inside of an if statement, nothing to be scared of. However, when I was scanning the method looking for an error I had made, this line would constantly stop me dead in my tracks. I just couldn't scan it. Every time I had to stop and break it down manually in my head. Largely because I had to stop and figure out what each If was actually doing in the expression.
I have since rewritten the line as
If report.IsPublicReport.GetValueOrDefault() Then Return True
While more verbose, I am finding that this disrupts my train of thought less as I am scanning the code.
This got me thinking,
Is this something other more experienced
VB.net developers are running into?
Are there any other types of
expressions that are largely
avoided, or at least not favored?
Am I just whining about nothing?

As long as you are uncomfortable with VB.NET syntax, I would strongly recommend you use Option Strict On so you catch mistakes like these quicker. The best way is by changing it globally so it is always on by default. Tools + Options, Projects and Solutions, VB Defaults, change Option Strict to "On".

What you're describing is something Scott Hanselman (and probably others) call "Code smell".
It's basically the idea that when you look at a piece of code and something doesn't seem "right" about it. This is not a capability that developers just "have". It's something you develop over time as you read and write more and more code.
It's not just VB either, you'll see plenty of idiomatic constructs in every language that will (or should) make you pause and question what you're looking at.
That Double IF would definitely do it for me

In Vb.NET you can write:
row!FirstName = "Test"
instead of
row("FirstName") = "Test"
A while ago I used to write row!FirstName (you can do that with every item in a collection that can be accessed by a string parameter) because I thought that was a good idea because it looks more statically typed (like person.FirstName as a property) and is shorter.
However I realized that this is not a good idea because after changing "FirstName" to "Name" i often looked for String in the current file which are highlited in Visual Studio (the object!param syntax is not).
Which makes finding them harder.

You can write
Private Sub Form1_Load() Handles MyBase.Load
End Sub
instead of
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
which is fine if you don't need sender or e (I suppose it is just some compiler magic that adds the signature itself) but I refuse to use the shorter way, cause you don't recognize it as an eventhandler at first sight.

Related

How to find missing "handles" clauses in a vb.net project?

We have a VS solution containing multiple VB projects. From time to time, some of the Handles clauses from procedure declarations get lost (which, for example, seems to happen when moving a control from one container to another one), causing non functioning buttons etc. in our software.
We're in the process to add an AddHandlers() sub to every class, in which we add the handlers manually, so Handles clauses will no be longer necessary. Until then, we have to keep an eye on those disappearing clauses.
Though we use Subversion, we don't always notice that a clause got lost.
Is there a we can have Visual Studio automatically check for missing Handles clauses? Maybe we could use some mighty black magic regex stuff for this task? Anybody have an idea?

Testing for DLL references in VBA

First, apologies for the generic title - if anyone can suggest a better one, I'd be happy to change it, but right now, I have no clue where to start.
I have a workbook utilizing a DLL to access a data provider (Bloomberg), and the requirements to get it to work correctly are quite tricky. Furthermore, deployment is a nightmare, since users might need to reference the DLL themselves.
Naturally, I first check wether the library is referenced, before testing the library itself.
Here's my code (which is working as intended) :
Public Sub TestBloomberg()
Dim ref As Object
Dim fRef As Boolean
fRef = False
For Each ref In ThisWorkbook.VBProject.References
If ref.GUID = "{4AC751C2-BB10-4702-BB05-791D93BB461C}" Then
If Not ref.IsBroken Then
fRef = True
End If
End If
Next
If fRef Then
' In separate Sub to get around User-defined type error
Call TestBloombergConnection
ElseIf Not fRef Then
' warn user about missing reference
End If
End Sub
As you can see, if the reference to the DLL is set, I proceed checking if the library works as intended (this has a lot of external factors at play, such as wether the server-application is running, the user is logged in, etc.) You can think of this as a simple ON-ERROR-GOTO-wrapped call to the dll.
I am forced to move the actual test of the functionality to another sub, as called from the second if-block. If I have no (or a broken) reference to the dll, even though the library will not be called itself, I will get a User-defined Error. If I move the exact same code to another sub, it will work perfectly.
Finally, my question:
What happens when I run my VBA code, why do I get a (i think) runtime error during compile time? How can my code be so dependend on external factors, that it can't even get to the point of failing?
What this behavior demonstrates is that VBA compiles separate subroutines separately and at different times. I had a similar situation when I was trying to resolve references on behalf of the users (solving a versioning problem, which I got to work, but then abandoned as not worth the trouble).
When you are ready to enter a subroutine, it interprets only as much as it needs to, and you could get a compile time error then, even though to you it seems like you are at run time.
The error you are actually getting is probably a 429 Automation error or something similar. You would get that if you have a broken link (dll moved, deleted, or not registered). What I remember from my project, is that I could reliably handle it if a good reference was saved in the file, or no reference was saved, but if a bad reference was saved, the code had to be isolated similar to what you found. I think I had mine in a separate class, but the principle is the same.
I think this "interpret only as much as necessary" is considered a feature of VBA. You can run a certain section of code, even if you have compile errors elsewhere. This can be useful when you only have a partially written functions or other half-finished stuff, or if you open the file on a computer without some referenced software installed. It lets at least some of the functionality still work.

Is use of Mid(), Instr(), LBound(), UBound() etc. in VB.Net not recommended?

I come from a C# background but am now working mostly with VB.Net. It seems to me that the above functions (and others - eg. UCase, LCase) etc. are carryovers from VB6 and before. Is the use of these functions frowned upon in VB.Net, or does it purely come down to personal preference?
My personal preference is to stay well away from them, but I'm wondering if that is just my C# prejudice.
I've come across a couple of issues - particularly with code converted from VB6 to VB.Net, where the 0 indexing of collections has meant that bugs have been introduced into code, and am therefore wary of them.
The reason that those functions are there in the first place is of course that they are part of the VB language, inherited from VB 6.
However, they are not just wrappers for methods in the framework, some of them have some additional logic that makes them different in some ways. The Mid function for example allows that you specify a range that is outside the string, and it will silently reduce the range and return the part of the string that remains. The String.Substring method instead throws an exception if you specify a range outside the string.
So, the functions are not just wrappers, they represent a different approach to programming that is more in line with Visual Basic, where you can throw just about anything at a function and almost always get something out. In some ways that is easier, as you don't have to think about all the special cases, but on the other hand you might want to get an exception instead of getting a result when you feed something unreasonable to a function. When debugging, it's often easier if you get the exception as early as possible instead of trying to trace back where a faulty value comes from.
Those options are for backward compatibility.
But, it will be better for people to use framework classes/methods to ensure consistency.
Having said that, VB6 functions are easy to understand. So, it should not be an issue for someone who has the VB background.
EDIT: Also, some of the overloads available with framework classes, might not be available with an equivalent of a simple VB6 like statement. I cannot remember of any, as of now - But this is what I think, could be a better reason to use framework classes/methods.
There will be special cases, but, Hands down, use the VB6 versions, unless you care about the difference between a string being "" and Nothing.
I was working on a big project where different programmers using both ways, the code where people used MyString.SubString(1) was blowing up while Mid(MyString,2) was working.
The two main errors for this example: (Which apply in various ways to others as well)
(1) String can be nothing and you have to check before running a method on it. Limitation of the OO notation: You can't call a member method if the object is nothing, even if you want 'nothing' or (empty object) back. Even if this were solved by using nullable/stub objects for strings (which you kind of can using "" or string.empty), you'd still have to ensure they're initialized properly - or, as in our case - convert Nothing to "" when receiving strings from library calls beyond our control.
You are going to have strings that are Nothing. 90% of the time you'll want it to mean "". with .SubString, you always have to check for nothing. With the VB versions, only the 10% about which you'll care.
(2) Specifically with the Mid example, again, 90% of the time if you want chars 3-10 of a 2 char string, you'll want to see "" returned, not have it throw an exception! In fact, you'll rarely want an exception: you'll have to check first for the proper length and code how it should behave (there is usually a defined behaviour, at the very least, a data entry error, for which you don't want to throw an exception).
So you're checking 100% of the time with the .Net versions and rarely with the VB versions.
.Net wanted to keep everything into the object-oriented philosophy. But strings are a little different than most objects used in subtle ways. MS-Basic wasn't thinking about this when they made the functions, it just got lucky - one of the strengths of functions is that they can handle null objects.
For our project, one may ask how Nothing strings got into our flow in the first place. But in the end, the decision of some programmers to use the .Net functions meant avoidable service calls, emergency bug fixes, and patches. Save yourself the trouble.
I would avoid them. Since you've mentioned them it sounds as though you've inherited some VB6 code that was possibly converted to a VB.NET project. Otherwise, if it was a new VB.NET project, I see no value in using the VB6 methods.
I've been on a few VB6 to VB.NET conversion projects. While I am familiar with the names and the difference in 0 based indexing, any code I came across got refactored to use their .NET equivalents. This was partially for consistency and to get the VB6 programmers on that project familiar with the framework. However, the other benefit I've found in refactoring is the ability to chain method calls together.
Consider the following:
Dim input As String = "hello world"
Dim result As String = input.ToUpper() ' .NET
Dim result As String = UCase(input) ' VB6
Next thing you know, I need to do more work to satisfy other requirements. Let's say I need to take the substring and get "hello," which results in the code getting updated to:
Dim result As String = input.ToUpper().Substring(0, 5) ' .NET
Dim result As String = Mid(UCase(input), 1, 5) ' VB6
Which is clearer and easier to modify? In .NET I just chain it. In VB6 I had to start at the beginning of the method, then go to the end of it and add the closing parenthesis. If it changes again or I need to remove it, in .NET I just chop off the end, but in VB6 I need to backtrack to the start and end.
I think there's value in using the .NET methods since other .NET developers that join the project later, especially those from a C# background, can easily pick it up.

Is it possible for the Vb.Net compiler to switch on an "Unreachable code" warning?

I've been mostly working with VB.Net for over a year and just noticed this
Am I going insane, or does VB.Net NOT have an "Unreachable code" warning?
The following compiles quite happily with nary a warning or error, even though there is a return between the two writeline calls.
Sub Main()
Console.WriteLine("Hello World")
Return
Console.WriteLine("Unreachable code, will never run")
End Sub
Am I missing something? Is there some way to switch this on that I can't find.
If not, is there a good reason for its omission? (i.e. or am I right in thinking this is a woeful state of affairs)
Forgive the air of rant about this question, it's not a rant, I would like an answer.
Thanks
I've raised this on MS Connect, as bug# 428529
Update
I received the following from the VB Teams program manager
Thanks for taking the time to report
this issue. The compiler has limited
support for this scenario, and as you
point out we don't have warnings for
unreachable code. There are some
scenarios that our flow analysis
algorithm does handle, such as the
following:
Sub Main()
Dim x As Integer
Return
x = 4
End Sub
In this case you'll get a warning that
x has never been assigned. For the
case you mentioned however we'll have
to look at implementing that for a
future release.
My guess is that it's an oversight in the compiler. Flow control is a very difficult problem to get correct in any language, but especially in a language like VB which has so many different flow control mechanisms. For instance,
Exceptions
Goto
On Error (Resume, Goto, etc ...)
Exit calls
If you feel strongly about this issue, please file a bug on Connect. We do take bugs filed via Connect very seriously and do our best to fix as many as possible.
They mention this in the following post:
https://stackoverflow.com/questions/210187/usage-statistics-c-versus-vb-net
See the last post.
I guess you could use FXCop to check your code instead or get a copy of Resharper from:
http://www.jetbrains.com/resharper/
I'd like to address Jared's answer.
Most of the issues he brings up are not problematic for data flow analysis.
The one exception is "On Error / Resume". They mess up data flow analysis pretty bad.
However, it's a pretty simple problem to mitigate:
If more than one "On Error" statement is used in a method, or the "Resume next" statement is used, you can just turn off data flow analysis and report a generic warning. A good one might be something like "On Error / Resume are deprecated, use exceptions instead." :)
In the common case of one only "On Error" statement and no "resume" statement, you can pretty much do normal data flow analysis, and should get reasonable results from it.
The big problem is with the way the existing DFA code is implemented. It doesn't use a control flow graph, and so changing it ends up being really expensive. I think if you want to address these kinds of issues you really need rip out the existing DFA code and replace it with something that uses a control flow graph.
AFAIK, you are correct that VB.NET does not give you a warning. C# does though.

What are the IDE advantages of recorded macros?

Just as the title says, I see a lot of editors touting macro recording as a feature but cannot find a way to take advantage of these functions myself. So what can you use it for? The type where you can record mouse movement and/or keystrokes? Is it really that helpful to people out there? Specifically, I deal with Eclipse which has a number of built in "fill in" functions, so I really don't see what the advantages could be.
I use them all the time. Say, for example, I want to go down a list, indenting by 4 and adding a "|* ". In EMACS, I hit C-x ( to start recording, do one example line to see that it's what I want, ending with C-n C-a to move to the next line, and end the macro with C-x ). Then C-x e repeats it line by line, and C-u number C-x e does it many times.
Depends on what you are doing and what language you are work with. As a simple example, right now I am working with a Visual Basic .NET application that has a number of queries in it. I generally do all of my work with queries in Toad, but Visual Basic .NET has an annoying syntax when it comes to long strings, namely:
Public Const SelectData As String = _
"SELECT * " & _
"FROM myTable " & _
"WHERE myField = :SOMETHING"
Since I really don't like editing the queries when I copy them out of the code or pasting them back in, I have some macros that will automatically format or strip the formatting from them.
Also, some of the macros can be used to automate common tasks that you need to do around the IDE while you are working. Any sequence of commands that you see yourself doing often is something that you can turn into a macro and do with just a single click.
Waaaay back I used a macro to make function header/comments. Other than that I have not used them.
Basically you can "automate" tedious things you do often that do not have built in ways to do the tasks you do frequently. It is a flexible way to give lots of power to people so they can work more efficiently.
I find it very useful in microsoft excel. Rather then having to look through documentation to find every object and function I need to call I can record a macro that does most of what I want, take that code and modify it to give me finer control.
In Visual Studio, I use macros for many different purposes. One of the most valuable comes when debugging Windows service. I can use the macro engine to start and then attach to the Windows service which just a click of a button.
Also, sometimes I use custom DEFINES that need to be exploded into code--sort of like C/C++ macros.
Colby Africa
I don't use them in Eclipse either.
Here's why:
Eclipse has many powerful built-in functions and refactorings. So with code, its not necessary.
Eclipse macros aren't that great. You can record them, but its hard to tweak them and do exactly what you want.
Macros become more useful in things like modifying files that aren't code. For that I tend to use something like vim. Also, you have to actually practice using macros to recognize when they will help.