Does anyone here use VB.NET and have a strong preference for or against using IsNothing as opposed to Is Nothing (for example, If IsNothing(anObject) or If anObject Is Nothing...)? If so, why?
EDIT: If you think they're both equally acceptable, do you think it's best to pick one and stick with it, or is it OK to mix them?
If you take a look at the MSIL as it's being executed you'll see that it doesn't compile down to the exact same code. When you use IsNothing() it actually makes a call to that method as opposed to just evaluating the expression.
The reason I would tend to lean towards using "Is Nothing" is when I'm negating it becomes "IsNot Nothing' rather than "Not IsNothing(object)" which I personally feel looks more readable.
I find that Patrick Steele answered this question best on his blog: Avoiding IsNothing()
I did not copy any of his answer here, to ensure Patrick Steele get's credit for his post. But I do think if you're trying to decide whether to use Is Nothing or IsNothing you should read his post. I think you'll agree that Is Nothing is the best choice.
Edit - VoteCoffe's comment here
Partial article contents: After reviewing more code I found out another reason you should avoid this: It accepts value types! Obviously, since IsNothing() is a function that accepts an 'object', you can pass anything you want to it. If it's a value type, .NET will box it up into an object and pass it to IsNothing -- which will always return false on a boxed value! The VB.NET compiler will check the "Is Nothing" style syntax and won't compile if you attempt to do an "Is Nothing" on a value type. But the IsNothing() function compiles without complaints. -PSteele – VoteCoffee
You should absolutely avoid using IsNothing()
Here are 4 reasons from the article IsNothing() VS Is Nothing
Most importantly, IsNothing(object) has everything passed to it as an object, even value types! Since value types cannot be Nothing, it’s a completely wasted check.
Take the following example:
Dim i As Integer
If IsNothing(i) Then
' Do something
End If
This will compile and run fine, whereas this:
Dim i As Integer
If i Is Nothing Then
' Do something
End If
Will not compile, instead the compiler will raise the error:
'Is' operator does not accept operands of type 'Integer'.
Operands must be reference or nullable types.
IsNothing(object) is actually part of part of the Microsoft.VisualBasic.dll.
This is undesirable as you have an unneeded dependency on the VisualBasic library.
Its slow - 33.76% slower in fact (over 1000000000 iterations)!
Perhaps personal preference, but IsNothing() reads like a Yoda Condition. When you look at a variable you're checking its state, with it as the subject of your investigation.
i.e. does it do x? --- NOT Is xing a property of it?
So I think If a IsNot Nothing reads better than If Not IsNothing(a)
I agree with "Is Nothing". As stated above, it's easy to negate with "IsNot Nothing".
I find this easier to read...
If printDialog IsNot Nothing Then
'blah
End If
than this...
If Not obj Is Nothing Then
'blah
End If
VB is full of things like that trying to make it both "like English" and comfortable for people who are used to languages that use () and {} a lot.
And on the other side, as you already probably know, most of the time you can use () with function calls if you want to, but don't have to.
I prefer IsNothing()... but I use C and C#, so that's just what is comfortable. And I think it's more readable. But go with whatever feels more comfortable to you.
I'm leaning towards the "Is Nothing" alternative, primarily because it seems more OO.
Surely Visual Basic ain't got the Ain't keyword.
I initially used IsNothing but I've been moving towards using Is Nothing in newer projects, mainly for readability. The only time I stick with IsNothing is if I'm maintaining code where that's used throughout and I want to stay consistent.
Is Nothing requires an object that has been assigned to the value Nothing. IsNothing() can take any variable that has not been initialized, including of numeric type. This is useful for example when testing if an optional parameter has been passed.
Related
So I have this:
Dim aBoolean As Boolean = True
Will it make any difference to just do this?
Dim aBoolean = True
In other languages, I believe it was a good practice to also define the type of variable it would be, for performance or something. I am not entirely sure with VB.NET.
Thanks.
It depends. Explicitly defining the variable can improve readability, but I don't think it's always necessary. (To be clear, it has nothing to do with the actual functionality of your code).
In this specific example, you follow the declaration with a Boolean assignment of True, so it's already crystal clear that aBoolean is actually a Boolean when it is declared. The As Boolean syntax is not as necessary in this scenario.
Other cases may not be so clear. If the declaration was followed by the result of a function call, for example, it might be more clear to explicitly declare that the variable is a Boolean. e.g.
Dim aBoolean As Boolean = TestValidityOfObject(o)
As long as you have Option Infer turned on, it won't make a bit of difference. The second line is just a syntactic abbreviation for the first. At that point, it's up to your style preference as to which you should use.
Before type inference, there were performance issues when not declaring the type, but that's no longer an issue; due to type inference the variable will be of type Boolean whether you declare it or not.
Declaring the type can help the compiler catch errors sooner, and will often give you better Intellisense.
You're using what's called "type inference". This is where the compiler figures out at compile time what the type on the right side of the assignment is and uses that as the type of the variable.
This is, in general, a safe and convenient feature. However, there are a couple of things to keep in mind:
You must have Option Infer on; otherwise, the compiler doesn't do type inference and, depending on your setting for Option Strict, instead either gives you a compile time error (Option Strict On) or types your variable as Object and uses late binding everywhere. This is Pure Evil. (Option Strict Off)
In your particular case, there's no way for the compiler to mess up. HOWEVER, it's possible to use type inference in such a way as to change the semantics of your code:
For instance...
Dim myClass as MyBaseClass = New SubClass()
This is perfectly legal; we're typing the variable as a base class and assigning a value to it that represents an instance of a subclass. Nothing special. However, if we switch to type inference by just removing the type declaration...
Dim myClass = New SubClass()
Type inference will now see myClass as a SubClass instead of MyBaseClass. This might seem obvious, but the point is that you should be aware of what it's doing.
For more information and long-winded discussion about using type inference, see this question. While that question is targeted at C#, the only real difference is the first item that I listed above. Everything else is conceptually the same.
Does cleanliness trump performance here:
Version 1:
Function MyFunc(ByVal param as String) As String
Dim returnValue as String
If param Is Nothing Then
returnValue = "foo"
Else
returnValue = param
return returnValue
Version 2:
Function MyFunc(ByVal param as String) As String
return If(param,"foo")
Version 1 deals directly with unboxed Strings. Version 2 deals with all boxed Objects. [If() takes a TestExpression as Object, a FalsePart as Object and returns an Object]
[can't add comments]
COMMENT: ja72, fixed my naming.
COMMENT: Marc, so you would go with Version 2?
I think clarity trumps anything.
The If(obj1,obj2) function is the null coalescing operator of VB.NET. It functions the same as obj1 ?? obj2 in C#. As such, everyone should know what it means, and it should be used where conciseness is important.
Although the If/Else statement is clean, simple, and obvious, in this particular case, I would favor the If function.
The compiler would optimize these two to the same code or nearly the same depending on the optimization level (See project properties).
Write two methods this way, compile them and use Reflector to look into the VB.Net decompiled code (or even MSIL) and you will see that there is very little (some billionth of a second) or none difference in exectuion.
Compiler optimizations generally handle normal patterns that allows you to write if-statements and loops in different ways. For instance in .Net for, foreach, while, do, etc do not actually exist. They are language specific features that are compiled down to goto-statement logic in the assembly level. Use Reflector to look at a few of these and you'll learn a lot! :)
Note that it is possible to write bad code that the compiler can't optimize to its "best state", and it is even possible to do better than the compiler. Understanding .Net assembly and MSIL means understanding the compiler better.
Really? I don't think this function is going to be a bottleneck in any application, and so just go with brevity/clarity.
I would recommend:
Public Function TXV(ByVal param As String) As String
Return If(param Is Nothing, "foo", param)
End Function
and make sure the function returns a string (to keep type safety). BTW, why is your Function called MySub ? Shouldn't it be MyFunc ?
I believe that these two implementations are nearly the same, I would use the second one because it's shorter.
Since I come from a C background, I would opt for the ternary operator most times where it is clear what is happening - in a case like this where there is repetition and it can be idiomatic. Similarly in T-SQL where you can use COALESCE(a, b, c, d, e) to avoid having a bunch of conditionals and simply take the first non-null value - this is idiomatic and easily read.
Beware that the old IIf function is different from the new If operator, so while the new one properly handles side-effects and short-circuits, it's only one character away from a completely different behavior which people have long been wary of.
http://secretgeek.net/iif_function.asp
http://visualbasic.about.com/od/usingvbnet/a/ifop.htm
I don't think it's going to matter in terms of performance, because the optimizer is pretty good about these kind of transforms.
I maintain a program which can be automated via COM. Generally customers use VBS to do their scripting, but we have a couple of customers who use Matlab's ActiveX support and are having trouble calling COM object methods with a NULL parameter.
They've asked how they do this in Matlab - and I've been scouring Mathworks' COM/ActiveX documentation for a day or so now and can't figure it out.
Their example code might look something like this:
function do_something()
OurAppInstance = actxserver('Foo.Application');
OurAppInstance.Method('Hello', NULL)
end
where NULL is where in another language, we'd write NULL or nil or Nothing, or, of course, pass in an object. The problem is this is optional (and these are implemented as optional parameters in most, but not all, cases) - these methods expect to get NULL quite often.
They tell me they've tried [] (which from my reading seemed the most likely) as well as '', Nothing, 'Nothing', None, Null, and 0. I have no idea how many of those are even valid Matlab keywords - certainly none work in this case.
Can anyone help? What's Matlab's syntax for a null pointer / object for use as a COM method parameter?
Update: Thanks for all the replies so far! Unfortunately, none of the answers seem to work, not even libpointer. The error is the same in all cases:
Error: Type mismatch, argument 2
This parameter in the COM type library is described in RIDL as:
HRESULT _stdcall OurMethod([in] BSTR strParamOne, [in, optional] OurCoClass* oParamTwo, [out, retval] VARIANT_BOOL* bResult);
The coclass in question implements a single interface descending from IDispatch.
I'm answering my own question here, after talking to Matlab tech support: There is no equivalent of Nothing, and Matlab does not support this.
In detail: Matlab does support optional arguments, but does not support passing in variant NULL pointers (actually, to follow exactly how VB's Nothing works, a VT_EMPTY variant, I think) whether as an optional argument or not. There is documentation about some null / pointerish types, a lot of which is mentioned in my question or in various answers, but these don't seem to be useable with their COM support.
I was given a workaround by Matlab support using a COM DLL they created and Excel to create a dummy nothing object that could be passed around in scripts. I haven't managed to get this workaround / hack working, and even if I had unfortunately I probably could not redistribute it. However, if you encounter the same problem this description might give you a starting point at least!
Edit
It is possible this Old New Thing blog post may be related. (I no longer work with access to the problematic source code, or access to Matlab, to refresh my memory or to test.)
Briefly, for IUnknown (or derived) parameters, you need a [unique] attribute for them to legally be NULL. The above declaration required Matlab create or pass in a VT_EMPTY variant, which it couldn't do. Perhaps adding [unique] may have prompted the Matlab engine to pass in a NULL pointer (or variant containing a NULL pointer), instead - assuming it was able to do that, which is guesswork.
This is all speculation since this code and the intricacies of it are several years behind me at this point. However, I hope it helps any future reader.
From the mathworks documentation, you can use the libpointer function:
p = libpointer;
and then p will be a NULL pointer. See that page for more details.
See also: more information about libpointer.
Peter's answer should work, but something you might want to try is NaN, which is what Matlab ususally uses as a NULL value.
In addition to using [] and libpointer (as suggested by Peter), you can also try {}.
The correct answer for something in VB that is expecting a Nothing argument, is to somehow get a COM/ActiveX Variant which has a variant type of VT_EMPTY. (see MSDN docs which reference marshaling behavior for Visual Basic Nothing)
MATLAB may do this with the empty array ([]), but I'm not sure.... so it may not be possible purely in MATLAB. Although someone could easily write a tiny COM library whose purpose is to create a Variant with VT_EMPTY.
But if the argument has the [optional] atttribute, and you want to leave that optional argument blank, you should not do this. See the COM/ActiveX docs on Variants which say under VT_EMPTY:
VT_EMPTY: No value was specified. If an optional argument to an Automation method is left blank, do not pass a VARIANT of type VT_EMPTY. Instead, pass a VARIANT of type VT_ERROR with a value of DISP_E_PARAMNOTFOUND.
Matlab should (but probably does not) provide methods to create these objects (a "nothing" and an "optional blank") so you can interface correctly with COM objects.
Simple question, from a readability standpoint, which method name do you prefer for a boolean method:
public boolean isUserExist(...)
or:
public boolean doesUserExist(...)
or:
public boolean userExists(...)
public boolean userExists(...)
Would be my prefered. As it makes your conditional checks far more like natural english:
if userExists ...
But I guess there is no hard and fast rule - just be consistent
I would say userExists, because 90% of the time my calling code will look like this:
if userExists(...) {
...
}
and it reads very literally in English.
if isUserExist and if doesUserExist seem redundant.
Beware of sacrificing clarity whilst chasing readability.
Although if (user.ExistsInDatabase(db)) reads nicer than if (user.CheckExistsInDatabase(db)), consider the case of a class with a builder pattern, (or any class which you can set state on):
user.WithName("Mike").ExistsInDatabase(db).ExistsInDatabase(db2).Build();
It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist. You wouldn't write if (user.Age()) or if (user.Name()) without any comparison value, so why is if (user.Exists()) a good idea purely because that property/function is of boolean type and you can rename the function/property to read more like natural english? Is it so bad to follow the same pattern we use for other types other than booleans?
With other types, an if statement compares the return value of a function to a value in code, so the code looks something like:
if (user.GetAge() >= 18) ...
Which reads as "if user dot get age is greater than or equal to 18..." true - it's not "natural english", but I would argue that object.verb never resembled natural english and this is simply a basic facet of modern programming (for many mainstream languages). Programmers generally don't have a problem understanding the above statement, so is the following any worse?
if (user.CheckExists() == true)
Which is normally shortened to
if (user.CheckExists())
Followed by the fatal step
if (user.Exists())
Whilst it has been said that "code is read 10x more often than written", it is also very important that bugs are easy to spot. Suppose you had a function called Exists() which causes the object to exist, and returns true/false based on success. You could easily see the code if (user.Exists()) and not spot the bug - the bug would be very much more obvious if the code read if (user.SetExists()) for example.
Additionally, user.Exists() could easily contain complex or inefficient code, round tripping to a database to check something. user.CheckExists() makes it clear that the function does something.
See also all the responses here: Naming Conventions: What to name a method that returns a boolean?
As a final note - following "Tell Don't Ask", a lot of the functions that return true/false disappear anyway, and instead of asking an object for its state, you tell it to do something, which it can do in different ways based on its state.
The goal for readability should always be to write code the closest possible to natural language. So in this case, userExists seems the best choice. Using the prefix "is" may nonetheless be right in another situations, for example isProcessingComplete.
My simple rule to this question is this:
If the boolean method already HAS a verb, don't add one. Otherwise, consider it. Some examples:
$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
I would go with userExists() because 1) it makes sense in natural language, and 2) it follows the conventions of the APIs I have seen.
To see if it make sense in natural language, read it out loud. "If user exists" sounds more like a valid English phrase than "if is user exists" or "if does user exist". "If the user exists" would be better, but "the" is probably superfluous in a method name.
To see whether a file exists in Java SE 6, you would use File.exists(). This looks like it will be the same in version 7. C# uses the same convention, as do Python and Ruby. Hopefully, this is a diverse enough collection to call this a language-agnostic answer. Generally, I would side with naming methods in keeping with your language's API.
There are things to consider that I think were missed by several other answers here
It depends if this is a C++ class method or a C function. If this is a method then it will likely be called if (user.exists()) { ... } or if (user.isExisting()) { ... }
not if (user_exists(&user)) .
This is the reason behind coding standards that state bool methods should begin with a verb since they will read like a sentence when the object is in front of them.
Unfortunately lots of old C functions return 0 for success and non-zero for failure so it can be difficult to determine the style being used unless you follow the all bool functions begin with verbs or always compare to true like so if (true == user_exists(&user))
Why not rename the property then?
if (user.isPresent()) {
Purely subjective.
I prefer userExists(...) because then statements like this read better:
if ( userExists( ... ) )
or
while ( userExists( ... ) )
In this particular case, the first example is such horrible English that it makes me wince.
I'd probably go for number three because of how it sounds when reading it in if statements. "If user exists" sounds better than "If does user exists".
This is assuming it's going to be to used in if statement tests of course...
I like any of these:
userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
Method names serves for readability, only the ones fit into your whole code would be the best which most of the case it begins with conditions thus subjectPredicate follows natural sentence structure.
Since I follow the convention to put verb before function name, I would do the same here too:
//method name
public boolean doesExists(...)
//this way you can also keep a variable to store the result
bool userExists = user.doesExists()
//and use it like a english phrase
if (userExists) {...}
//or you can use the method name directly also and it will make sense here too
if (user.doesExists()) {...}
VB.NET has a very handy "with" statement, but it also lets you use it on an unnamed variable, like this:
With New FancyClass()
.Level = "SuperSpiffy"
.Style = Slimming
.Execute()
End With
Is there a way to get at the "hidden" instance, so I can view its properties in the Immediate window? I doubt I'll get it in the watch windows, so immediate is fine.
If you try to access the instance the same way (say, when .Execute() throws an exception) from the Immediate window, you get an error:
? .Style
'With' contexts and statements are not valid in debug windows.
Is there any trick that can be used to get this, or do I have to convert the code to another style? If With functioned more like a Using statement, (e.g. "With v = New FancyClass()") this wouldn't pose a problem.
I know how With is working, what alternatives exist, what the compiler does, etc. I just want to know if this is possible.
As answered, the simple answer is "no".
But isn't another way to do it: instead of declaring and then cleaning up the variable is to use the "Using".
Using fc as new FancyClass()
With fc
.Level = "SuperSpiffy"
.Style = Slimming
.Execute()
End With
End Using
Then you can use fc in the immediate window and don't have to remember to write a
fc=nothing
line.
Just some more thoughts on it ;)
What's wrong with defining a variable on one line and using it in a with-statement on the next? I realise it keeps the variable alive longer but is that so appalling?
Dim x = new SomethingOrOther()
With x
.DoSomething()
End With
x = Nothing ' for the memory conscious
Two extra lines wont kill you =)
Edit: If you're just looking for a yes/no, I'd have to say: No.
I hope there really isn't a way to get at it, since the easy answer is "no", and I haven't found a way yet either. Either way, nothing said so far really has a rationale for being "no", just that no one has =) It's just one of those things you figure the vb debugger team would have put in, considering how classic "with" is =)
Anyway, I know all about usings and Idisposable, I know how to fix the code, as some would call it, but I might not always want to.
As for Using, I don't like implementing IDisposable on my classes just to gain a bit of sugar.
What we really need is a "With var = New FancyClass()", but that might just be confusing!
You're creating a variable either way - in the first case (your example) the compiler is creating an implicit variable that you aren't allowed to really get to, and the in the second case (another answer, by Oli) you'd be creating the variable explicitly.
If you create it explicitly you can use it in the immediate window, and you can explicitly destroy it when you're through with it (I'm one of the memory conscious, I guess!), instead of leaving those clean up details to the magic processes. I don't think there is any way to get at an implicit variable in the immediate window. (and I don't trust the magic processes, either. I never use multiple-dot notation or implicit variables for this reason)