Chapter 3
A (really) short comparison with C# and Visual Basic
This short chapter is for readers who programmed in Visual Basic and C# before and want either to switch completely to X# or want to use X# for specific projects. Both are possible and X# might make you a little more productive as a developer because the syntax might be a little easier to use and is more familiar to Visual Basic developers.
The most important statement about X# is that X# is 100% based on the CLR and is 100% .Net language. Therefore it uses the same type system, the same date types, although the names will be different, the same exception handling, etc. as any other .Net language. It's no problem of course to reference any C# or VB assembly and vice versa. Most of the language features of C# are part of X# as well.
Important: All syntax elements described in this chapter are based on the core dialect of X#. They may differ if another dialect like VO is used. In addition, the X# compilers offer a rich set of switches that allow to change core aspects of the syntax like case sensitivity, the need to use self for referencing instance members, and even the base index of an array which can be set to 0 instead of 1.
X# syntax overview
The syntax of X# offers an interesting mixture between the syntax of Visual Basic and C#. The similarities are:
-
no curly braces
-
no semicolons at the end of a line
-
no distinction between lower and upper case per default (this can be changed through the compiler switch -cs)
-
definitions and control structures can end with an (in some cases optional) end command (at the end)
-
the array index starts with 1 (this can be changed through the compiler switch -az)
Of course, the main reason for the syntax of X# is the fact that is based on Visual Objects (VO for short) which derived from the de facto xBase standard (if you don't know the "historical facts" yet, its always a pleasure to take a ride back in history on Wikipedia: https://de.wikipedia.org/wiki/Visual_Objects' - and it's always interesting to note that any article on a "xBase topic" is much more detailed in German than in English). So the data type Logical for example has been part of the original xBase data types and therefore existed since the mid-80s.
Line continuation
X# has many great language features that make it equal, or in some cases a little superior, to C# and Visual Basic, the need for line continuation character is not one of those features.
With the current version of X#, every line has to have a ; at the end, if it spans multiple rows in the editor. Otherwise, the compilers produce error messages like "END NAMESPACE expected".
Although I recommend breaking long lines into several smaller lines, I would not argue with developers who prefer a single line even if it means having to scroll to the right a couple of times (on the other hand, an ultra-wide 40" monitor is a good argument for not having to use semicolons;).
Fig 3.1: A missing line continuation character leads to several errors
NOTE: Whereas C# has no need for a line continuation character, in Visual Basic some lines have to end with a _ character.
A short comparison with C
The most important differences have already been mentioned in the last sections. There are a few situations where an X# developer has to learn and use the C# syntax. For Lambda expression in the immediate window during debugging or for setting a breakpoint condition. But this will change with each new release. In X# 2.13 it's already possible to use self or the : operator in the immediate window. And with X# 2.17 there had to be more improvements to make using the immediate window for expression evaluation as close to C# as possible. Since C# is case-sensitive, keeping the lower and upper case consistent for a variable name is still important.
And don't forget the equivalent of the continue is Loop. Otherwise, you will get an interesting-looking exception out of nowhere.
A short comparison with Visual Basic
As a long-time VB developer who started with the first version of Visual Basic in 1991 (codename "thunder") X# looks like the perfect successor to Visual Basic for me. It avoids formalities like case sensitivity and having to worry about curly braces and semicolons and it uses the same self-explanatory keywords I liked in the Visual Basic syntax. For example, property definitions in a class can be done like in Visual Basic.
But this does not mean, of course, that X# is in any way compatible with Visual Basic. There is no equivalent for My or Option Explicit for example, there is no WithEvents and more syntax elements might be missing too.
I am mostly referring to the syntax in general.
For me, X#, especially when using it with Visual Studio, is in many ways a better Visual Basic with many ingredients from C# without the "restrictions" like having to end statements with a semicolon.
Most Visual Basic developers should like the X# syntax. In opposite to Visual Basic, X# is still under active development and will be for the foreseeable future. Although X# is not from Microsoft and may not contain all the language features of VB, I recommend trying X# for future projects instead of Visual Basic.
Let the code speak for itself
To give all readers a truly objective comparison between X#, C#, and Visual Basic, I will present a small console application that reads some data from a SQLite database in all three languages (the details will be explained in Chapter 16).
It's interesting to note that the X# version comprises only 36 lines, the C# version, as expected, 47 lines, and the VB version 41 lines. Of course, it is always possible to save a few lines, like omitting the curly braces in C# when the following block consists only of a single command. Starting with C# version 9 it would be even possible to completely omit the class definition with a static main method by using only top-level statements. In this mode, it's not even necessary to define a start function (Visual Basic does not have this language feature).
So, how does X# compare with Visual Basic? Both languages have many syntax elements in common. There is no direct equivalent to the var keyword in VB, but the Dim statement comes close if Option Infer On has not been set to off. The X# program in this section had been compiled with the standard Core dialect. In the VO dialect the functions of the X# runtime are very similar to the functions of the VB runtime like Instr(), Len(), or Val(). For many of these functions, there is a direct equivalent in X#. Visual Basic developers, who might switch to X#, will not only get a familiar syntax but literally over a hundred, mostly familiar, functions that are part of the VB runtime. X# has no equivalent to the practical My namespace in VB, but it would be no problem at all to reference the Microsoft.VisualBasic assembly in an X# project so that My can be used in an X# application too.
**Example 3.1: (XS_DbQueryXS.prg) **
// A simple database query with X# and a datareader
// Compile with xsc /r:runtimeLibs/SQLite x64/System.Data.SQLite.dll
Using System.Data
Using System.Data.Sqlite
Using System.Collections.Generic
Internal Class Book
Internal Property Title As String Auto
End Class
Function Start() As Void
Console.WriteLine("*** This is X# ***")
Var books := List<Book>{}
Var cnStr := "Data Source=./BookLib.db3"
Local cn := Null As SqliteConnection
Try
cn := SQliteConnection{cnStr}
cn:open()
var cmd := cn:CreateCommand()
cmd:CommandText := "Select * From Book"
var dr := cmd:ExecuteReader()
While dr:Read()
books:Add(Book{}{Title := dr:GetString(dr:GetOrdinal("Title"))})
End While
Catch ex As SystemException
Console.WriteLine(i"Error: {ex:Message}")
Finally
If cn != Null
cn:Close()
EndIf
End Try
ForEach var book in Books
Console.WriteLine(String.Format("Title: {0}", book:Title))
Next
Return
**Example 3.2: (XS_DbQueryCS.cs) **
// A simple database query with C# and a datareader
using System;
using System.Data;
using System.Data.SQLite;
using System.Collections.Generic;
internal class Book
{
internal string Title {get; set;}
}
class Application
{
static void Main()
{
Console.WriteLine("*** This is C# ***");
var books = new List<Book>();
var cnStr = "Data Source=./BookLib.db3";
SQLiteConnection cn = null;
try
{
cn = new SQLiteConnection(cnStr);
cn.Open();
var cmd = cn.CreateCommand();
cmd.CommandText = "Select * From Book";
var dr = cmd.ExecuteReader();
while (dr.Read())
{
books.Add(new Book(){Title = dr.GetString(dr.GetOrdinal("Title"))});
}
}
catch(SystemException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
if(cn != null)
cn.Close();
}
foreach(var book in books)
{
Console.WriteLine($"Title: {book.Title}");
}
}
}
**Example 3.3: (XS_DbQueryVB.vb) **
' A simple database query with Visual Basic and a datareader
Imports System.Data
Imports System.Data.Sqlite
Imports System.Collections.Generic
Friend Class Book
Friend Property Title As String
End Class
Class Application
Shared Sub Main()
Console.WriteLine("*** This is Visual Basic ***")
Dim books As List(Of Book) = new List(Of Book)
Dim cnStr As String = "Data Source=./BookLib.db3"
Dim cn As SqliteConnection = Nothing
Try
cn = new SQliteConnection(cnStr)
cn.open()
Dim cmd = cn.CreateCommand()
cmd.CommandText = "Select * From Book"
Dim dr = cmd.ExecuteReader()
While dr.Read()
books.Add(new Book With {.Title = dr.GetString(dr.GetOrdinal("Title"))})
End While
Catch ex As SystemException
Console.WriteLine("Error: " + ex.Message)
Finally
If cn Is Nothing
cn.Close()
End If
End Try
For Each book in Books
Console.WriteLine(String.Format("Title: {0}", book.Title))
Next
Return
End Sub
End Class