Show/Hide Toolbars

XSharp

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()