As of build 2.0.0.8, X# also support Xbase++ style class declarations. Of course, we have added strong typing to the language definition to make the code run faster.
Full documentation will be included in one of the next builds.
The code below shows the Xbase++ support in action:
CLASS Developer
class var list as array // class vars are like static variables.
class VAR nextid as int
class var random as Random
PROTECTED:
VAR id as int NOSAVE // the Nosave clause will mark the field with the [NonSerialized] attribute
EXPORTED:
VAR FirstName as string
VAR LastName as string
VAR Country as string
// The inline prefix in the next line is needed when declaring a method inside the class .. endclass block.
INLINE METHOD initClass() // The Xbase++ equivalent of the Static constructor
list := {}
nextid := 1
random := Random{}
RETURN
INLINE METHOD Init(cFirst as string , cLast as string, cCountry as string) // Init is the constructor
// you can use :: instead of SELF:
::FirstName := cFirst
::LastName := cLast
::Country := cCountry
::id := nextid
nextid += 1
aadd(list, SELF)
RETURN
INLINE Method SayHello() as STRING
if ::Age < 40
RETURN "Hello, I am " + ::FirstName+ " from "+::Country
else
RETURN "Hello, I am mr " + ::LastName+ " from "+::Country+" but you can call me "+::FirstName
endif
INLINE METHOD FullName() as string
RETURN ::FirstName + " " + ::LastName
INLINE METHOD Fire() as logic
local nPos as dword
nPos := Ascan(list, SELF)
if nPos > 0
aDel(list, nPos)
ASize(list, aLen(list)-1)
return true
endif
return false
// the next block contains forward declarations. The methods has to be declared below the class .. endclass block
// SYNC method makes sure that only one thread can run this code at the same time
SYNC METHOD LivesIn
// ACCESS indicates a PROPERTY GET
// ASSIGN indicates a PROPERTY SET
ACCESS CLASS METHOD Length as dword
ACCESS METHOD Age as int
ENDCLASS
// This is the implementation of LivesIn. SYNC does not have to be repeated here
METHOD LivesIn(cCountry as string) as logic
return lower(::Country) == lower(cCountry)
// This is the implementation of the AGE Property. ACCESS does not have to be repeated here
METHOD Age() as int
local nAge as int
nAge := random:@@Next(25,60)
return nAge
// This is the implementation of the Length Property. ACCESS does not have to be repeated. CLASS however must be specified.
CLASS METHOD Length as dwor
return ALen(list)
// the entry point is Main() like in Xbase++
function Main(a) as int
local oDeveloper as Developer
local aDevs := {} as array
local i as int
if PCount() > 0
? "Parameters"
for i := 1 to PCount()
? _GetFParam(i)
next
endif
// create a new object with Xbase++ Syntax. Developer{} would have worked as well.
aadd(aDevs, Developer():New("Chris", "Pyrgas", "Greece"))
aadd(aDevs, Developer():New("Nikos", "Kokkalis","Greece"))
aadd(aDevs, Developer():New("Fabrice", "Foray","France"))
aadd(aDevs, Developer():New("Robert", "van der Hulst","The Netherlands"))
? "# of devs before", Developer.Length
for i := 1 to alen(aDevs)
oDeveloper := aDevs[i]
? "Fields", oDeveloper:FirstName, oDeveloper:LastName, oDeveloper:Country
? "FullName",oDeveloper:FullName()
? oDeveloper:SayHello()
? "Greece ?", oDeveloper:LivesIn("Greece")
? "Fired", oDeveloper:Fire()
? "# of devs after firing", oDeveloper:FirstName, Developer.Length
next
_wait()
RETURN PCount()