In our code I have seen many places where something is compared with nil.
Although it was never recommended it seems that it has worked in VO.
Is it better to rewrite it as Isnil(x) in X# or is the same code produced?
The expression "x == NIL" is being translated to a call to the equals (==) operator method of the usual class, which uses much code to test against the possible combinations of values and types of the 2 values being compared.
On the other hand, IsNil() is a simple function call and this function is optimized to check against NIL only.
So it should be much faster to make the comparison against NIL with IsNil(), than using x == NIL. Of course for a few comparisons the difference in speed is not noticeable, but it might make a difference in tight time critical loops.
I would say:
Empty in X#/Vulcan Runtime gives the same result as Empty in VO
Isnil in X#/Vulcan Runtime gives the same result as Isnil in VO
If an empty string "" is passed then Empty returns true, whereas isnil return false
If a number 0 is passed then Empty returns true, whereas isnil return false
if a null_object then Empty returns true and also isnil return true
In X# with the Vulcan Runtime together with the macro execution I have had some cases where instead of a nil usual variable a null pointer was passed to function/method. Until now I have not understood in which cases this can happen.
I have seen that working with usuals there is always a big risk using isnil/==nil and I have preferred using Empty.
What Arne said, IsNil() and Empty() check for different things.
Also IsNil() is a runtime function and its parameter type is USUAL, so you can use it only in the VO/Vulcan (or Harbour) dialects. And it is designed to work with USUAL vars, because the value NIL only makes sense in the context of the USUAL.
If you need a function that combines the Empty()/IsNil() functionality also in core, I would suggest to write a general function that behaves exactly the way you want it to, so you can use the same from all your apps.